diff --git a/.env.example b/.env.example deleted file mode 100644 index 20b84c2f0b..0000000000 --- a/.env.example +++ /dev/null @@ -1,9 +0,0 @@ -# Used to test fork deploy contract in packages/core -# seed-phrase for the wallet to use on goerli -MNEMONIC_GOERLI=xxxxxxxxxxxxxxxxxxxxxx - -# goerli provider URI -ETH_NODE_URI_GOERLI=xxxxxxxxxxxxxxxxxxxxxx - -# Options to increase Node process memory (useful when running yarn coverage for example on some machine) -NODE_OPTIONS=--max-old-space-size=8192 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 92ec5bb6dd..8c940538d7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,6 +27,8 @@ jobs: - name: Running tests run: yarn test:ci + env: + ETH_NODE_URI_POLYGON: ${{ secrets.ETH_NODE_URI_POLYGON }} coverage: runs-on: ubuntu-latest @@ -72,3 +74,4 @@ jobs: run: yarn deploy:ci env: ETH_NODE_URI_GOERLI: ${{ secrets.ETH_NODE_URI_GOERLI }} + ETH_NODE_URI_POLYGON: ${{ secrets.ETH_NODE_URI_POLYGON }} diff --git a/.gitignore b/.gitignore index 2bc04c0731..f1375a27e4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,7 @@ node_modules/ # yarn 3 .yarn/* -!.yarn/cache +.yarn/cache !.yarn/patches !.yarn/plugins !.yarn/releases diff --git a/README.md b/README.md index 0981f1edce..119812f8e4 100644 --- a/README.md +++ b/README.md @@ -50,13 +50,16 @@ yarn install - 📦 This mono-repository contains a suite of smart contract packages. - ⚖️ The mono-repository is released under [MIT license](./LICENSE). Note, that the packages may contain their own licenses. -| Package | Version | License | Description | -|---------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|------------------------------------------| -| [`@sandbox-smart-contracts/packages/core`](./packages/core) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/core)](https://www.npmjs.com/package/@sandbox-smart-contracts/core) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🗝️ Core smart contracts (pre 2023) | -| [`@sandbox-smart-contracts/packages/deploy`](./packages/deploy) | N/A | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🚀 Deploy all packages (except core) | -| [`@sandbox-smart-contracts/packages/example-hardhat`](./packages/example-hardhat) | N/A | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 👷 Development template using Hardhat | -| [`@sandbox-smart-contracts/packages/giveaway`](./packages/giveaway) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/giveaway)](https://www.npmjs.com/package/@sandbox-smart-contracts/giveaway) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🎁 Instant Giveaway smart contract claims | -| [`@sandbox-smart-contracts/packages/dependency-metatx`](./packages/dependency-metatx) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/dependency-metatx)](https://www.npmjs.com/package/@sandbox-smart-contracts/giveaway) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🌐 Dependency: ERC2771 handler | +| Package | Version | License | Description | +|---------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [`@sandbox-smart-contracts/packages/core`](./packages/core) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/core)](https://www.npmjs.com/package/@sandbox-smart-contracts/core) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🗝️ Core smart contracts (pre 2023) | +| [`@sandbox-smart-contracts/packages/deploy`](./packages/deploy) | N/A | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🚀 Deploy all packages (except core) | +| [`@sandbox-smart-contracts/packages/example-hardhat`](./packages/example-hardhat) | N/A | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 👷 Development template using Hardhat | +| [`@sandbox-smart-contracts/packages/giveaway`](./packages/giveaway) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/giveaway)](https://www.npmjs.com/package/@sandbox-smart-contracts/giveaway) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🎁 Instant Giveaway smart contract claims | +| [`@sandbox-smart-contracts/packages/dependency-metatx`](./packages/dependency-metatx) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/dependency-metatx)](https://www.npmjs.com/package/@sandbox-smart-contracts/dependency-metatx) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🌐 Dependency: ERC2771 handler | +| [`@sandbox-smart-contracts/packages/dependency-royalty-management`](./packages/dependency-royalty-management) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/dependency-royalty-management)](https://www.npmjs.com/package/@sandbox-smart-contracts/royalty-management) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🎨 Dependency: The Sandbox Royalty Implementation in partnership with [Manifold's royalty-registry](https://github.com/manifoldxyz/royalty-registry-solidity/tree/main) | +| [`@sandbox-smart-contracts/packages/dependency-operator-filter`](./packages/dependency-operator-filter) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/dependency-operator-filter)](https://www.npmjs.com/package/@sandbox-smart-contracts/operator-filter) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🤝 Dependency: The Sandbox's implementation for OpenSea's operator filter | +| [`@sandbox-smart-contracts/packages/asset`](./packages/asset) | [![npm](https://img.shields.io/npm/v/@sandbox-smart-contracts/asset)](https://www.npmjs.com/package/@sandbox-smart-contracts/asset) | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html) | 🚗 Asset contract upgrade for L2 deployment featuring tiers, abilities, operator-filter and creator royalties | ## Contributing diff --git a/packages/asset/.eslintignore b/packages/asset/.eslintignore new file mode 100644 index 0000000000..a77e23ebbf --- /dev/null +++ b/packages/asset/.eslintignore @@ -0,0 +1,16 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts + +# generated docs +generated-markups + +# editors +.idea diff --git a/packages/asset/.eslintrc.js b/packages/asset/.eslintrc.js new file mode 100644 index 0000000000..e734de4058 --- /dev/null +++ b/packages/asset/.eslintrc.js @@ -0,0 +1,41 @@ +const path = require('path'); +const tsconfigPath = path.join(__dirname, 'tsconfig.json'); +module.exports = { + root: true, + extends: [ + 'eslint:recommended', + 'plugin:mocha/recommended', + 'plugin:prettier/recommended', + ], + parserOptions: { + ecmaVersion: 2020, + }, + plugins: ['mocha'], + env: { + commonjs: true, + node: true, + mocha: true, + }, + overrides: [ + { + files: ['*.ts'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: [tsconfigPath], + ecmaVersion: 2020, + sourceType: 'module', + }, + plugins: ['mocha', '@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:mocha/recommended', + 'plugin:prettier/recommended', + ], + rules: { + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-floating-promises': 'error', + }, + }, + ], +}; diff --git a/packages/asset/.gitignore b/packages/asset/.gitignore new file mode 100644 index 0000000000..742fc52217 --- /dev/null +++ b/packages/asset/.gitignore @@ -0,0 +1,16 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts +./artifacts +./cache +./typechain + +deploy +deployments diff --git a/packages/asset/.prettierignore b/packages/asset/.prettierignore new file mode 100644 index 0000000000..a77e23ebbf --- /dev/null +++ b/packages/asset/.prettierignore @@ -0,0 +1,16 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts + +# generated docs +generated-markups + +# editors +.idea diff --git a/packages/asset/.prettierrc.js b/packages/asset/.prettierrc.js new file mode 100644 index 0000000000..60dbb58db3 --- /dev/null +++ b/packages/asset/.prettierrc.js @@ -0,0 +1,15 @@ +module.exports = { + singleQuote: true, + bracketSpacing: false, + plugins: ['prettier-plugin-solidity'], + overrides: [ + { + files: '*.sol', + options: { + printWidth: 120, + tabWidth: 4, + singleQuote: false, + }, + }, + ], +}; diff --git a/packages/asset/.solcover.js b/packages/asset/.solcover.js new file mode 100644 index 0000000000..f6c4e5445d --- /dev/null +++ b/packages/asset/.solcover.js @@ -0,0 +1,7 @@ +module.exports = { + mocha: { + grep: '@skip-on-coverage', // Find everything with this tag + invert: true, // Run the grep's inverse set. + }, + skipFiles: ['/mock'], +}; diff --git a/packages/asset/.solhint.json b/packages/asset/.solhint.json new file mode 100644 index 0000000000..6333c2b430 --- /dev/null +++ b/packages/asset/.solhint.json @@ -0,0 +1,14 @@ +{ + "extends": "solhint:recommended", + "plugins": ["prettier"], + "rules": { + "prettier/prettier": [ + "error", + { + "endOfLine": "auto" + } + ], + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["error", {"ignoreConstructors": true}] + } +} diff --git a/packages/asset/.solhintignore b/packages/asset/.solhintignore new file mode 100644 index 0000000000..d28fc94993 --- /dev/null +++ b/packages/asset/.solhintignore @@ -0,0 +1 @@ +contracts/mock diff --git a/packages/asset/README.md b/packages/asset/README.md new file mode 100644 index 0000000000..87756be292 --- /dev/null +++ b/packages/asset/README.md @@ -0,0 +1,71 @@ +# + +The Sandbox Asset package for deploying on Polygon + +## Running the project locally + +Install dependencies with `yarn` + +Testing: Use `yarn test` inside `packages/` to run tests locally inside this package + +For testing from root (with workspace feature) use: `yarn workspace @sandbox-smart-contracts/ test` + +Coverage: Run `yarn coverage` + +Formatting: Run `yarn prettier` to check and `yarn prettier:fix` to fix formatting errors + +Linting: Run `yarn lint` to check and `yarn lint:fix` to fix static analysis errors + +## Package structure and minimum standards + +#### A NOTE ON DEPENDENCIES + +1. Add whatever dependencies you like inside your package; this template is for hardhat usage. OpenZeppelin contracts + are highly recommended and should be installed as a dev dependency +2. For most Pull Requests there should be minimum changes to `yarn.lock` at root level +3. Changes to root-level dependencies are permissible, however they should not be downgraded +4. Take care to run `yarn` before pushing your changes +5. You shouldn't need to install dotenv since you won't be deploying inside this package (see below) + +#### UNIT TESTING + +1. Unit tests are to be added in `packages//test` +2. Coverage must meet minimum requirements for CI to pass +3. `getSigners` return an array of addresses, the first one is the default `deployer` for contracts, under no + circumstances should tests be written as `deployer` +4. It's permissible to create mock contracts at `packages//contracts/mock` e.g. for third-party contracts +5. Tests must not rely on any deploy scripts from the `deploy` package; your contracts must be deployed inside the test + fixture. See `test/fixtures.ts` + +# Deployment + +Each package must unit-test the contracts by running everything inside the `hardhat node`. Deployment to "real" +networks, configuration of our environment and integration tests must be done inside the `deploy` package. + +The `deploy` package only imports `.sol` files. The idea is to recompile everything inside it and manage the entire +deploy strategy from one place. + +1. Your deploy scripts should not be included inside `packages/`: deploy scripts live inside `packages/deploy/` +2. The `deploy` package doesn't use the hardhat config file from the specific package. Instead, it + uses `packages/deploy/hardhat.config.ts` +3. You will need to review `packages/deploy/hardhat.config.ts` and update it as needed for any new namedAccounts you + added to your package +4. When it comes to deploy time, it is preferred to include deploy scripts and end-to-end tests as a separate PR +5. The named accounts inside the `deploy` package must use the "real-life" values +6. Refer to the readme at `packages/deploy` to learn more about importing your package + +#### INTEGRATION TESTING + +1. End-to-end tests live at `packages/deploy/` +2. You must add end-to-end tests ahead of deploying your package. Importantly, these tests should verify deployment and + initialization configuration + +# A NOTE ON MAKING PULL REQUESTS + +1. Follow the PR template checklist +2. Your PR will not be approved if the above criteria are not met + + + + + diff --git a/packages/asset/contracts/Asset.sol b/packages/asset/contracts/Asset.sol new file mode 100644 index 0000000000..26520fc93a --- /dev/null +++ b/packages/asset/contracts/Asset.sol @@ -0,0 +1,375 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import { + AccessControlUpgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; +import { + ERC1155BurnableUpgradeable, + ERC1155Upgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol"; +import { + ERC1155SupplyUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol"; +import { + ERC1155URIStorageUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; +import { + MultiRoyaltyDistributor +} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol"; +import { + OperatorFiltererUpgradeable, + IOperatorFilterRegistry +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol"; +import {TokenIdUtils} from "./libraries/TokenIdUtils.sol"; +import {IAsset} from "./interfaces/IAsset.sol"; +import {ITokenUtils, IRoyaltyUGC} from "./interfaces/ITokenUtils.sol"; + +/// @title Asset +/// @author The Sandbox +/// @notice ERC1155 asset token contract +/// @notice Minting and burning tokens is only allowed through separate authorized contracts +/// @dev This contract is final and should not be inherited +contract Asset is + IAsset, + Initializable, + ERC2771HandlerUpgradeable, + ERC1155BurnableUpgradeable, + AccessControlUpgradeable, + ERC1155SupplyUpgradeable, + ERC1155URIStorageUpgradeable, + OperatorFiltererUpgradeable, + MultiRoyaltyDistributor, + ITokenUtils +{ + using TokenIdUtils for uint256; + + bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); + bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); + bytes32 public constant MODERATOR_ROLE = keccak256("MODERATOR_ROLE"); + + // mapping of ipfs metadata token hash to token id + mapping(string => uint256) public hashUsed; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Initialize the contract + /// @param forwarder The address of the trusted forwarder + /// @param assetAdmin The address of the asset admin + /// @param baseUri The base URI for the token metadata + /// @param commonSubscription The address of the operator filter subscription + /// @param _manager The address of the royalty manager + function initialize( + address forwarder, + address assetAdmin, + string memory baseUri, + address commonSubscription, + address _manager + ) external initializer { + _setBaseURI(baseUri); + __AccessControl_init(); + __ERC1155Supply_init(); + __ERC2771Handler_init(forwarder); + __ERC1155Burnable_init(); + _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin); + __OperatorFilterer_init(commonSubscription, true); + __MultiRoyaltyDistributor_init(_manager); + } + + /// @notice Mint new tokens + /// @dev Only callable by the minter role + /// @param to The address of the recipient + /// @param id The id of the token to mint + /// @param amount The amount of the token to mint + /// @param metadataHash The metadata hash of the token to mint + function mint( + address to, + uint256 id, + uint256 amount, + string memory metadataHash + ) external onlyRole(MINTER_ROLE) { + _setMetadataHash(id, metadataHash); + _mint(to, id, amount, ""); + address creator = id.getCreatorAddress(); + _setTokenRoyalties(id, payable(creator), creator); + } + + /// @notice Mint new tokens with catalyst tier chosen by the creator + /// @dev Only callable by the minter role + /// @param to The address of the recipient + /// @param ids The ids of the tokens to mint + /// @param amounts The amounts of the tokens to mint + /// @param metadataHashes The metadata hashes of the tokens to mint + function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts, + string[] memory metadataHashes + ) external onlyRole(MINTER_ROLE) { + require(ids.length == metadataHashes.length, "Asset: 1-Array mismatch"); + require(ids.length == amounts.length, "Asset: 2-Array mismatch"); + for (uint256 i = 0; i < ids.length; i++) { + _setMetadataHash(ids[i], metadataHashes[i]); + } + _mintBatch(to, ids, amounts, ""); + for (uint256 i; i < ids.length; i++) { + address creator = ids[i].getCreatorAddress(); + _setTokenRoyalties(ids[i], payable(creator), creator); + } + } + + /// @notice Burn a token from a given account + /// @dev Only the minter role can burn tokens + /// @dev This function was added with token recycling and bridging in mind but may have other use cases + /// @param account The account to burn tokens from + /// @param id The token id to burn + /// @param amount The amount of tokens to burn + function burnFrom( + address account, + uint256 id, + uint256 amount + ) external onlyRole(BURNER_ROLE) { + _burn(account, id, amount); + } + + /// @notice Burn a batch of tokens from a given account + /// @dev Only the minter role can burn tokens + /// @dev This function was added with token recycling and bridging in mind but may have other use cases + /// @dev The length of the ids and amounts arrays must be the same + /// @param account The account to burn tokens from + /// @param ids An array of token ids to burn + /// @param amounts An array of amounts of tokens to burn + function burnBatchFrom( + address account, + uint256[] memory ids, + uint256[] memory amounts + ) external onlyRole(BURNER_ROLE) { + _burnBatch(account, ids, amounts); + } + + /// @notice Set a new URI for specific tokenid + /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash + /// @param tokenId The token id to set URI for + /// @param metadata The new URI for asset's metadata + function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) { + _setURI(tokenId, metadata); + } + + /// @notice Set a new base URI + /// @param baseURI The new base URI + function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) { + _setBaseURI(baseURI); + } + + /// @notice returns full token URI, including baseURI and token metadata URI + /// @param tokenId The token id to get URI for + /// @return tokenURI the URI of the token + function uri(uint256 tokenId) + public + view + override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable) + returns (string memory tokenURI) + { + return ERC1155URIStorageUpgradeable.uri(tokenId); + } + + /// @notice returns the tokenId associated with provided metadata hash + /// @param metadataHash The metadata hash to get tokenId for + /// @return tokenId the tokenId associated with the metadata hash + function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256 tokenId) { + return hashUsed[metadataHash]; + } + + /// @notice sets the metadata hash for a given tokenId + /// @param tokenId The tokenId to set metadata hash for + /// @param metadataHash The metadata hash to set + function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal { + if (hashUsed[metadataHash] != 0) { + require(hashUsed[metadataHash] == tokenId, "Asset: Hash already used"); + } else { + hashUsed[metadataHash] = tokenId; + _setURI(tokenId, metadataHash); + } + } + + /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only + /// @dev Change the address of the trusted forwarder for meta-TX + /// @param trustedForwarder The new trustedForwarder + function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(trustedForwarder != address(0), "Asset: Zero address"); + _setTrustedForwarder(trustedForwarder); + } + + /// @notice Query if a contract implements interface `id`. + /// @param id the interface identifier, as specified in ERC-165. + /// @return supported `true` if the contract implements `id`. + function supportsInterface(bytes4 id) + public + view + virtual + override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor) + returns (bool supported) + { + return id == type(IRoyaltyUGC).interfaceId || super.supportsInterface(id); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata msgData) + { + return ERC2771HandlerUpgradeable._msgData(); + } + + function _beforeTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) { + super._beforeTokenTransfer(operator, from, to, ids, amounts, data); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @dev call data should be optimized to order ids so packedBalance can be used efficiently. + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param amounts amount of each token type transfered. + /// @param data additional data accompanying the transfer. + function safeBatchTransferFrom( + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) public virtual override onlyAllowedOperator(from) { + super.safeBatchTransferFrom(from, to, ids, amounts, data); + } + + /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens. + /// @param operator address which will be granted rights to transfer all tokens of the caller. + /// @param approved whether to approve or revoke + function setApprovalForAll(address operator, bool approved) + public + virtual + override + onlyAllowedOperatorApproval(operator) + { + _setApprovalForAll(_msgSender(), operator, approved); + } + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param amount amount of token transfered. + /// @param data additional data accompanying the transfer. + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) public virtual override onlyAllowedOperator(from) { + require(from == _msgSender() || isApprovedForAll(from, _msgSender()), "Asset: Transfer error"); + _safeTransferFrom(from, to, id, amount, data); + } + + /// @notice could be used to deploy splitter and set tokens royalties + /// @param tokenId the id of the token for which the EIP2981 royalty is set for. + /// @param recipient the royalty recipient for the splitter of the creator. + /// @param creator the creator of the tokens. + function setTokenRoyalties( + uint256 tokenId, + address payable recipient, + address creator + ) external override onlyRole(DEFAULT_ADMIN_ROLE) { + _setTokenRoyalties(tokenId, recipient, creator); + } + + /// @notice Extracts the creator address from a given token id + /// @param tokenId The token id to extract the creator address from + /// @return creator The asset creator address + function getCreatorAddress(uint256 tokenId) external pure returns (address creator) { + return TokenIdUtils.getCreatorAddress(tokenId); + } + + /// @notice Extracts the tier from a given token id + /// @param tokenId The token id to extract the tier from + /// @return tier The asset tier, determined by the catalyst used to create it + function getTier(uint256 tokenId) external pure returns (uint8 tier) { + return TokenIdUtils.getTier(tokenId); + } + + /// @notice Extracts the revealed flag from a given token id + /// @param tokenId The token id to extract the revealed flag from + /// @return revealed Whether the asset is revealed or not + function isRevealed(uint256 tokenId) external pure returns (bool revealed) { + return TokenIdUtils.isRevealed(tokenId); + } + + /// @notice Extracts the asset nonce from a given token id + /// @param tokenId The token id to extract the asset nonce from + /// @return creatorNonce The asset creator nonce + function getCreatorNonce(uint256 tokenId) external pure returns (uint16 creatorNonce) { + return TokenIdUtils.getCreatorNonce(tokenId); + } + + /// @notice Extracts the abilities and enhancements hash from a given token id + /// @param tokenId The token id to extract reveal nonce from + /// @return revealNonce The reveal nonce of the asset + function getRevealNonce(uint256 tokenId) external pure returns (uint16 revealNonce) { + return TokenIdUtils.getRevealNonce(tokenId); + } + + /// @notice Extracts the bridged flag from a given token id + /// @param tokenId The token id to extract the bridged flag from + /// @return bridged Whether the asset is bridged or not + function isBridged(uint256 tokenId) external pure returns (bool bridged) { + return TokenIdUtils.isBridged(tokenId); + } + + /// @notice This function is used to register Asset contract on the Operator Filterer Registry of OpenSea. Can only be called by admin. + /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list. + /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe. + /// @param subscribe bool to signify subscription "true"" or to copy the list "false". + function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) + external + onlyRole(DEFAULT_ADMIN_ROLE) + { + require(subscriptionOrRegistrantToCopy != address(0), "Asset: Zero address"); + _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe); + } + + /// @notice sets the operator filter registry address + /// @param registry the address of the registry + function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(registry != address(0), "Asset: Zero address"); + OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry); + } + + uint256[49] private __gap; +} diff --git a/packages/asset/contracts/AssetCreate.sol b/packages/asset/contracts/AssetCreate.sol new file mode 100644 index 0000000000..993b5e60e5 --- /dev/null +++ b/packages/asset/contracts/AssetCreate.sol @@ -0,0 +1,318 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol"; +import { + AccessControlUpgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; +import {TokenIdUtils} from "./libraries/TokenIdUtils.sol"; +import {AuthSuperValidator} from "./AuthSuperValidator.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; +import {IAsset} from "./interfaces/IAsset.sol"; +import {ICatalyst} from "./interfaces/ICatalyst.sol"; +import {IAssetCreate} from "./interfaces/IAssetCreate.sol"; + +/// @title AssetCreate +/// @author The Sandbox +/// @notice User-facing contract for creating new assets +contract AssetCreate is + IAssetCreate, + Initializable, + ERC2771HandlerUpgradeable, + EIP712Upgradeable, + AccessControlUpgradeable, + PausableUpgradeable +{ + using TokenIdUtils for uint256; + + IAsset private assetContract; + ICatalyst private catalystContract; + AuthSuperValidator private authValidator; + + // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token + mapping(address => uint16) public creatorNonces; + mapping(address => uint16) public signatureNonces; + + bytes32 public constant SPECIAL_MINTER_ROLE = keccak256("SPECIAL_MINTER_ROLE"); + bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); + + bytes32 public constant MINT_TYPEHASH = + keccak256("Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)"); + bytes32 public constant MINT_BATCH_TYPEHASH = + keccak256( + "MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)" + ); + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Initialize the contract + /// @param _name The name of the contract (for EIP712) + /// @param _version The version of the contract (for EIP712) + /// @param _assetContract The address of the asset contract + /// @param _catalystContract The address of the catalyst contract + /// @param _authValidator The address of the AuthSuperValidator contract + /// @param _forwarder The address of the forwarder contract + /// @param _defaultAdmin The address of the default admin + function initialize( + string memory _name, + string memory _version, + address _assetContract, + address _catalystContract, + address _authValidator, + address _forwarder, + address _defaultAdmin + ) public initializer { + assetContract = IAsset(_assetContract); + catalystContract = ICatalyst(_catalystContract); + authValidator = AuthSuperValidator(_authValidator); + __ERC2771Handler_init(_forwarder); + __EIP712_init(_name, _version); + __AccessControl_init(); + __Pausable_init(); + _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin); + } + + /// @notice Create a new asset + /// @param signature A signature generated by TSB + /// @param tier The tier of the asset to mint + /// @param amount The amount of the asset to mint + /// @param revealed Whether the asset is revealed or not + /// @param metadataHash The metadata hash of the asset to mint + /// @param creator The address of the creator + function createAsset( + bytes memory signature, + uint8 tier, + uint256 amount, + bool revealed, + string calldata metadataHash, + address creator + ) external whenNotPaused { + require( + authValidator.verify( + signature, + _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash) + ), + "AssetCreate: Invalid signature" + ); + + uint256 tokenId = + TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false); + + // burn catalyst of a given tier + catalystContract.burnFrom(creator, tier, amount); + assetContract.mint(creator, tokenId, amount, metadataHash); + emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed); + } + + /// @notice Create multiple assets at once + /// @param signature A signature generated by TSB + /// @param tiers The tiers of the assets to mint + /// @param amounts The amounts of the assets to mint + /// @param revealed Whether the assets are revealed or not + /// @param metadataHashes The metadata hashes of the assets to mint + /// @param creator The address of the creator + function createMultipleAssets( + bytes memory signature, + uint8[] calldata tiers, + uint256[] calldata amounts, + bool[] calldata revealed, + string[] calldata metadataHashes, + address creator + ) external whenNotPaused { + require( + authValidator.verify( + signature, + _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes) + ), + "AssetCreate: Invalid signature" + ); + + require(tiers.length == amounts.length, "AssetCreate: Arrays must be same length"); + require(amounts.length == metadataHashes.length, "AssetCreate: Arrays must be same length"); + require(metadataHashes.length == revealed.length, "AssetCreate: Arrays must be same length"); + + uint256[] memory tokenIds = new uint256[](tiers.length); + uint256[] memory tiersToBurn = new uint256[](tiers.length); + for (uint256 i = 0; i < tiers.length; i++) { + tiersToBurn[i] = tiers[i]; + tokenIds[i] = TokenIdUtils.generateTokenId( + creator, + tiers[i], + ++creatorNonces[creator], + revealed[i] ? 1 : 0, + false + ); + } + + catalystContract.burnBatchFrom(creator, tiersToBurn, amounts); + + assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes); + emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed); + } + + /// @notice Create special assets, like TSB exclusive tokens + /// @dev Only callable by the special minter + /// @param signature A signature generated by TSB + /// @param amount The amount of the asset to mint + /// @param metadataHash The metadata hash of the asset to mint, + /// @param creator The address of the creator + function createSpecialAsset( + bytes memory signature, + uint256 amount, + string calldata metadataHash, + address creator + ) external onlyRole(SPECIAL_MINTER_ROLE) whenNotPaused { + require( + authValidator.verify( + signature, + _hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash) + ), + "AssetCreate: Invalid signature" + ); + + uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false); + + assetContract.mint(creator, tokenId, amount, metadataHash); + emit SpecialAssetMinted(creator, tokenId, 0, amount, metadataHash, true); + } + + /// @notice Pause the contracts mint and burn functions + function pause() external onlyRole(PAUSER_ROLE) { + _pause(); + } + + /// @notice Unpause the contracts mint and burn functions + function unpause() external onlyRole(PAUSER_ROLE) { + _unpause(); + } + + /// @notice Get the asset contract address + /// @return assetContractAddress The asset contract address + function getAssetContract() external view returns (address assetContractAddress) { + return address(assetContract); + } + + /// @notice Get the catalyst contract address + /// @return catalystContractAddress The catalyst contract address + function getCatalystContract() external view returns (address catalystContractAddress) { + return address(catalystContract); + } + + /// @notice Get the auth validator address + /// @return authValidatorAddress The auth validator address + function getAuthValidator() external view returns (address authValidatorAddress) { + return address(authValidator); + } + + /// @notice Creates a hash of the mint data + /// @param creator The address of the creator + /// @param nonce The nonce of the creator + /// @param tier The tier of the asset + /// @param amount The amount of copies to mint + /// @param revealed Whether the asset is revealed or not + /// @param metadataHash The metadata hash of the asset + /// @return digest The hash of the mint data + function _hashMint( + address creator, + uint16 nonce, + uint8 tier, + uint256 amount, + bool revealed, + string calldata metadataHash + ) internal view returns (bytes32 digest) { + digest = _hashTypedDataV4( + keccak256( + abi.encode( + MINT_TYPEHASH, + creator, + nonce, + tier, + amount, + revealed, + keccak256((abi.encodePacked(metadataHash))) + ) + ) + ); + } + + /// @notice Creates a hash of the mint batch data + /// @param creator The address of the creator + /// @param nonce The nonce of the creator + /// @param tiers The tiers of the assets + /// @param amounts The amounts of copies to mint + /// @param revealed Whether the assets are revealed or not + /// @param metadataHashes The metadata hashes of the assets + /// @return digest The hash of the mint batch data + function _hashBatchMint( + address creator, + uint16 nonce, + uint8[] calldata tiers, + uint256[] calldata amounts, + bool[] calldata revealed, + string[] calldata metadataHashes + ) internal view returns (bytes32 digest) { + digest = _hashTypedDataV4( + keccak256( + abi.encode( + MINT_BATCH_TYPEHASH, + creator, + nonce, + keccak256(abi.encodePacked(tiers)), + keccak256(abi.encodePacked(amounts)), + keccak256(abi.encodePacked(revealed)), + _encodeHashes(metadataHashes) + ) + ) + ); + } + + /// @notice Encodes the hashes of the metadata for signature verification + /// @param metadataHashes The hashes of the metadata + /// @return encodedHashes The encoded hashes of the metadata + function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) { + bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length); + for (uint256 i = 0; i < metadataHashes.length; i++) { + encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i]))); + } + + return keccak256(abi.encodePacked(encodedHashes)); + } + + /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only + /// @dev Change the address of the trusted forwarder for meta-TX + /// @param trustedForwarder The new trustedForwarder + function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(trustedForwarder != address(0), "AssetCreate: Zero address"); + _setTrustedForwarder(trustedForwarder); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } + + uint256[45] private __gap; +} diff --git a/packages/asset/contracts/AssetReveal.sol b/packages/asset/contracts/AssetReveal.sol new file mode 100644 index 0000000000..af746b9567 --- /dev/null +++ b/packages/asset/contracts/AssetReveal.sol @@ -0,0 +1,464 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {EIP712Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol"; +import { + AccessControlUpgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; +import {TokenIdUtils} from "./libraries/TokenIdUtils.sol"; +import {AuthSuperValidator} from "./AuthSuperValidator.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; +import {IAsset} from "./interfaces/IAsset.sol"; +import {IAssetReveal} from "./interfaces/IAssetReveal.sol"; + +/// @title AssetReveal +/// @author The Sandbox +/// @notice Contract for burning and revealing assets +contract AssetReveal is + IAssetReveal, + Initializable, + AccessControlUpgradeable, + ERC2771HandlerUpgradeable, + EIP712Upgradeable, + PausableUpgradeable +{ + using TokenIdUtils for uint256; + IAsset private assetContract; + AuthSuperValidator private authValidator; + + // mapping of creator to asset id to asset's reveal nonce + mapping(address => mapping(uint256 => uint16)) internal revealIds; + + // mapping for showing whether a revealHash has been used + // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting + mapping(bytes32 => bool) internal revealHashesUsed; + + // allowance list for tier to be revealed in a single transaction + mapping(uint8 => bool) internal tierInstantRevealAllowed; + + bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); + + bytes32 public constant REVEAL_TYPEHASH = + keccak256( + "Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)" + ); + bytes32 public constant BATCH_REVEAL_TYPEHASH = + keccak256( + "BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)" + ); + bytes32 public constant INSTANT_REVEAL_TYPEHASH = + keccak256( + "InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)" + ); + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Initialize the contract + /// @param _assetContract The address of the asset contract + /// @param _authValidator The address of the AuthSuperValidator contract + /// @param _forwarder The address of the forwarder contract + function initialize( + string memory _name, + string memory _version, + address _assetContract, + address _authValidator, + address _forwarder, + address _defaultAdmin + ) public initializer { + assetContract = IAsset(_assetContract); + authValidator = AuthSuperValidator(_authValidator); + __ERC2771Handler_init(_forwarder); + __EIP712_init(_name, _version); + __AccessControl_init(); + __Pausable_init(); + _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin); + } + + /// @notice Reveal an asset to view its abilities and enhancements + /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId + /// @param tokenId the tokenId of id idasset to reveal + /// @param amount the amount of tokens to reveal + function revealBurn(uint256 tokenId, uint256 amount) external whenNotPaused { + _burnAsset(tokenId, amount); + emit AssetRevealBurn(_msgSender(), tokenId, amount); + } + + /// @notice Burn multiple assets to be able to reveal them later + /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately + /// @param tokenIds the tokenIds of the assets to burn + /// @param amounts the amounts of the assets to burn + function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external whenNotPaused { + _burnAssetBatch(tokenIds, amounts); + emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts); + } + + /// @notice Reveal assets to view their abilities and enhancements + /// @dev Can be used to reveal multiple copies of the same token id + /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer + /// @param prevTokenId The tokenId of the unrevealed asset + /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes) + /// @param metadataHashes The array of hashes for revealed asset metadata + /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId + function revealMint( + bytes memory signature, + uint256 prevTokenId, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) external whenNotPaused { + require(amounts.length == metadataHashes.length, "AssetReveal: 1-Array mismatch"); + require(amounts.length == revealHashes.length, "AssetReveal: 2-Array mismatch"); + require( + authValidator.verify( + signature, + _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes) + ), + "AssetReveal: Invalid signature" + ); + uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes); + emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes); + } + + /// @notice Mint multiple assets with revealed abilities and enhancements + /// @dev Can be used to reveal multiple copies of the same token id + /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer + /// @param prevTokenIds The tokenId of the unrevealed asset + /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes) + /// @param metadataHashes The array of hashes for asset metadata + /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId + function revealBatchMint( + bytes calldata signature, + uint256[] calldata prevTokenIds, + uint256[][] calldata amounts, + string[][] calldata metadataHashes, + bytes32[][] calldata revealHashes + ) external whenNotPaused { + require(prevTokenIds.length == amounts.length, "AssetReveal: 1-Array mismatch"); + require(amounts.length == metadataHashes.length, "AssetReveal: 2-Array mismatch"); + require(prevTokenIds.length == revealHashes.length, "AssetReveal: 3-Array mismatch"); + require( + authValidator.verify( + signature, + _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes) + ), + "AssetReveal: Invalid signature" + ); + uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length); + for (uint256 i = 0; i < prevTokenIds.length; i++) { + newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]); + } + emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes); + } + + /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction + /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements + /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer + /// @param prevTokenId The tokenId of the unrevealed asset + /// @param burnAmount The amount of assets to burn + /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount) + /// @param metadataHashes The array of hashes for asset metadata + /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId + function burnAndReveal( + bytes memory signature, + uint256 prevTokenId, + uint256 burnAmount, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) external whenNotPaused { + require(amounts.length == metadataHashes.length, "AssetReveal: 1-Array mismatch"); + require(amounts.length == revealHashes.length, "AssetReveal: 2-Array mismatch"); + uint8 tier = prevTokenId.getTier(); + require(tierInstantRevealAllowed[tier], "AssetReveal: Not allowed"); + require( + authValidator.verify( + signature, + _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes) + ), + "AssetReveal: Invalid signature" + ); + _burnAsset(prevTokenId, burnAmount); + uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes); + emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes); + } + + /// @notice Generate new tokenIds for revealed assets and mint them + /// @param prevTokenId The tokenId of the unrevealed asset + /// @param metadataHashes The array of hashes for asset metadata + /// @param amounts The array of amounts to mint + function _revealAsset( + uint256 prevTokenId, + string[] calldata metadataHashes, + uint256[] calldata amounts, + bytes32[] calldata revealHashes + ) internal returns (uint256[] memory) { + uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId); + for (uint256 i = 0; i < revealHashes.length; i++) { + require(revealHashesUsed[revealHashes[i]] == false, "AssetReveal: Hash already used"); + revealHashesUsed[revealHashes[i]] = true; + } + if (newTokenIds.length == 1) { + assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]); + } else { + assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes); + } + return newTokenIds; + } + + /// @notice Burns an asset to be able to reveal it later + /// @param tokenId the tokenId of the asset to burn + /// @param amount the amount of the asset to burn + function _burnAsset(uint256 tokenId, uint256 amount) internal { + _verifyBurnData(tokenId, amount); + assetContract.burnFrom(_msgSender(), tokenId, amount); + } + + function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal { + require(tokenIds.length == amounts.length, "AssetReveal: Invalid input"); + for (uint256 i = 0; i < tokenIds.length; i++) { + _verifyBurnData(tokenIds[i], amounts[i]); + } + assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts); + } + + function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure { + IAsset.AssetData memory data = tokenId.getData(); + require(!data.revealed, "AssetReveal: Already revealed"); + require(amount > 0, "AssetReveal: Invalid amount"); + } + + /// @notice Creates a hash of the reveal data + /// @param recipient The address of the recipient + /// @param prevTokenId The unrevealed token id + /// @param amounts The amount of tokens to mint + /// @param metadataHashes The array of hashes for new asset metadata + /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds) + /// @return digest The hash of the reveal data + function _hashInstantReveal( + address recipient, + uint256 prevTokenId, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) internal view returns (bytes32 digest) { + digest = _hashTypedDataV4( + keccak256( + abi.encode( + INSTANT_REVEAL_TYPEHASH, + recipient, + prevTokenId, + keccak256(abi.encodePacked(amounts)), + _encodeHashes(metadataHashes), + keccak256(abi.encodePacked(revealHashes)) + ) + ) + ); + } + + /// @notice Creates a hash of the reveal data + /// @param recipient The intended recipient of the revealed token + /// @param prevTokenId The previous token id + /// @param amounts The amount of tokens to mint + /// @param metadataHashes The array of hashes for new asset metadata + /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds) + /// @return digest The hash of the reveal data + function _hashReveal( + address recipient, + uint256 prevTokenId, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) internal view returns (bytes32 digest) { + digest = _hashTypedDataV4( + keccak256( + abi.encode( + REVEAL_TYPEHASH, + recipient, + prevTokenId, + keccak256(abi.encodePacked(amounts)), + _encodeHashes(metadataHashes), + keccak256(abi.encodePacked(revealHashes)) + ) + ) + ); + } + + /// @notice Creates a hash of the reveal data + /// @param recipient The intended recipient of the revealed tokens + /// @param prevTokenIds The previous token id + /// @param amounts The amounts of tokens to mint + /// @param metadataHashes The arrays of hashes for new asset metadata + /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds) + /// @return digest The hash of the reveal data + function _hashBatchReveal( + address recipient, + uint256[] calldata prevTokenIds, + uint256[][] calldata amounts, + string[][] calldata metadataHashes, + bytes32[][] calldata revealHashes + ) internal view returns (bytes32 digest) { + digest = _hashTypedDataV4( + keccak256( + abi.encode( + BATCH_REVEAL_TYPEHASH, + recipient, + keccak256(abi.encodePacked(prevTokenIds)), + _encodeBatchAmounts(amounts), + _encodeBatchHashes(metadataHashes), + _encodeBatchRevealHashes(revealHashes) + ) + ) + ); + } + + /// @notice Encodes the hashes of the metadata for signature verification + /// @param metadataHashes The hashes of the metadata + /// @return encodedHashes The encoded hashes of the metadata + function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) { + bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length); + for (uint256 i = 0; i < metadataHashes.length; i++) { + encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i]))); + } + return keccak256(abi.encodePacked(encodedHashes)); + } + + /// @notice Encodes the hashes of the metadata for signature verification + /// @param metadataHashes The hashes of the metadata + /// @return encodedHashes The encoded hashes of the metadata + function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) { + bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length); + for (uint256 i = 0; i < metadataHashes.length; i++) { + encodedHashes[i] = _encodeHashes(metadataHashes[i]); + } + return keccak256(abi.encodePacked(encodedHashes)); + } + + /// @notice Encodes the hashes of the metadata for signature verification + /// @param revealHashes The revealHashes + /// @return encodedRevealHashes The encoded hashes of the metadata + function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) { + bytes32[] memory encodedHashes = new bytes32[](revealHashes.length); + for (uint256 i = 0; i < revealHashes.length; i++) { + encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i])); + } + return keccak256(abi.encodePacked(encodedHashes)); + } + + /// @notice Encodes the amounts of the tokens for signature verification + /// @param amounts The amounts of the tokens + /// @return encodedAmounts The encoded amounts of the tokens + function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) { + bytes32[] memory encodedAmounts = new bytes32[](amounts.length); + for (uint256 i = 0; i < amounts.length; i++) { + encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i])); + } + return keccak256(abi.encodePacked(encodedAmounts)); + } + + /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't + /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed + /// @param metadataHashes The hashes of the metadata + /// @param prevTokenId The previous token id from which the assets are revealed + /// @return tokenIds The array of tokenIds to mint + function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId) + internal + returns (uint256[] memory tokenIds) + { + IAsset.AssetData memory data = prevTokenId.getData(); + require(!data.revealed, "AssetReveal: Already revealed"); + uint256[] memory tokenIdArray = new uint256[](metadataHashes.length); + for (uint256 i = 0; i < metadataHashes.length; i++) { + uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]); + if (tokenId == 0) { + uint16 revealNonce = ++revealIds[data.creator][prevTokenId]; + tokenId = TokenIdUtils.generateTokenId( + data.creator, + data.tier, + data.creatorNonce, + revealNonce, + data.bridged + ); + } + tokenIdArray[i] = tokenId; + } + return tokenIdArray; + } + + /// @notice Get the status of a revealHash + /// @return hashUsed Boolean representing whether the hash has been used + function revealHashUsed(bytes32 revealHash) external view returns (bool hashUsed) { + return revealHashesUsed[revealHash]; + } + + /// @notice Get the asset contract address + /// @return assetContractAddres The asset contract address + function getAssetContract() external view returns (address assetContractAddres) { + return address(assetContract); + } + + /// @notice Get the auth validator address + /// @return authValidatorContractAddress The auth validator address + function getAuthValidator() external view returns (address authValidatorContractAddress) { + return address(authValidator); + } + + /// @notice Set permission for instant reveal for a given tier + /// @param tier the tier to set the permission for + /// @param allowed allow or disallow instant reveal for the given tier + function setTierInstantRevealAllowed(uint8 tier, bool allowed) external onlyRole(DEFAULT_ADMIN_ROLE) { + tierInstantRevealAllowed[tier] = allowed; + } + + /// @notice Get permission for instant reveal for a given tier + /// @param tier The tier to check + /// @return instantRevealAllowed Boolean representing whether instant reveal is allowed for the given tier + function getTierInstantRevealAllowed(uint8 tier) external view returns (bool instantRevealAllowed) { + return tierInstantRevealAllowed[tier]; + } + + /// @notice Pause the contracts mint and burn functions + function pause() external onlyRole(PAUSER_ROLE) { + _pause(); + } + + /// @notice Unpause the contracts mint and burn functions + function unpause() external onlyRole(PAUSER_ROLE) { + _unpause(); + } + + /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only + /// @dev Change the address of the trusted forwarder for meta-TX + /// @param trustedForwarder The new trustedForwarder + function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(trustedForwarder != address(0), "AssetReveal: Zero address"); + _setTrustedForwarder(trustedForwarder); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } +} diff --git a/packages/asset/contracts/AuthSuperValidator.sol b/packages/asset/contracts/AuthSuperValidator.sol new file mode 100644 index 0000000000..662218d164 --- /dev/null +++ b/packages/asset/contracts/AuthSuperValidator.sol @@ -0,0 +1,54 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +/// @title AuthSuperValidator +/// @author The Sandbox +/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned +contract AuthSuperValidator is AccessControl { + mapping(address => address) private _signers; + + /// @dev Constructor + /// @param admin Address of the admin that will be able to grant roles + constructor(address admin) { + _grantRole(DEFAULT_ADMIN_ROLE, admin); + } + + /// @notice Sets the signer for a contract + /// @dev Only the admin can call this function + /// @param contractAddress Address of the contract to set the signer for + /// @param signer Address of the signer + function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) { + _signers[contractAddress] = signer; + } + + /// @notice Gets the signer for a contract + /// @param contractAddress Address of the contract to get the signer for + /// @return address of the signer + function getSigner(address contractAddress) public view returns (address) { + return _signers[contractAddress]; + } + + /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned + /// @dev Multipurpose function that can be used to verify signatures with different digests + /// @param signature Signature hash + /// @param digest Digest hash + /// @return bool + function verify(bytes memory signature, bytes32 digest) public view returns (bool) { + address signer = _signers[_msgSender()]; + require(signer != address(0), "AuthSuperValidator: No signer"); + address recoveredSigner = ECDSA.recover(digest, signature); + return recoveredSigner == signer; + } + + /// @notice Prevents the DEFAULT_ADMIN_ROLE from being renounced + /// @dev This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced + /// @param role Role to renounce + /// @param account Account to renounce the role for + function renounceRole(bytes32 role, address account) public override { + require(role != DEFAULT_ADMIN_ROLE, "AuthSuperValidator: cant renounce admin role"); + super.renounceRole(role, account); + } +} diff --git a/packages/asset/contracts/Catalyst.sol b/packages/asset/contracts/Catalyst.sol new file mode 100644 index 0000000000..d5af79da8b --- /dev/null +++ b/packages/asset/contracts/Catalyst.sol @@ -0,0 +1,317 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {ERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; +import { + AccessControlUpgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; +import { + ERC1155BurnableUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol"; +import { + ERC1155SupplyUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol"; +import { + ERC1155URIStorageUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import { + OperatorFiltererUpgradeable, + IOperatorFilterRegistry +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol"; +import { + RoyaltyDistributor +} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; +import {ICatalyst} from "./interfaces/ICatalyst.sol"; + +/// @title Catalyst +/// @author The Sandbox +/// @notice This contract manages catalysts which are used to mint new assets. +/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to +/// provide a variety of features including, AccessControl, URIStorage, Burnable and more. +/// The contract includes support for meta transactions. +contract Catalyst is + ICatalyst, + Initializable, + ERC1155Upgradeable, + ERC1155BurnableUpgradeable, + ERC1155SupplyUpgradeable, + ERC1155URIStorageUpgradeable, + ERC2771HandlerUpgradeable, + AccessControlUpgradeable, + OperatorFiltererUpgradeable, + RoyaltyDistributor +{ + bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); + bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); + + uint256 public highestTierIndex; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + modifier onlyValidId(uint256 tokenId) { + require(tokenId > 0 && tokenId <= highestTierIndex, "Catalyst: invalid catalyst id"); + _; + } + + /// @notice Initialize the contract, setting up initial values for various features. + /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://. + /// @param _trustedForwarder The trusted forwarder for meta transactions. + /// @param _subscription The subscription address. + /// @param _defaultAdmin The default admin address. + /// @param _defaultMinter The default minter address. + /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst. + /// @param _royaltyManager, the address of the Manager contract for common royalty recipient + function initialize( + string memory _baseUri, + address _trustedForwarder, + address _subscription, + address _defaultAdmin, + address _defaultMinter, + string[] memory _catalystIpfsCID, + address _royaltyManager + ) external initializer { + require(bytes(_baseUri).length != 0, "Catalyst: URI empty"); + require(_trustedForwarder != address(0), "Catalyst: 1-Zero address"); + require(_subscription != address(0), "Catalyst: 2-Zero address"); + require(_defaultAdmin != address(0), "Catalyst: 3-Zero address"); + require(_defaultMinter != address(0), "Catalyst: 4-Zero address"); + require(_royaltyManager != address(0), "Catalyst: 5-Zero address"); + __ERC1155_init(_baseUri); + __AccessControl_init(); + __ERC1155Burnable_init(); + __ERC1155Supply_init(); + __ERC1155URIStorage_init(); + __ERC2771Handler_init(_trustedForwarder); + __OperatorFilterer_init(_subscription, true); + _setBaseURI(_baseUri); + _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin); + _grantRole(MINTER_ROLE, _defaultMinter); + __RoyaltyDistributor_init(_royaltyManager); + for (uint256 i = 0; i < _catalystIpfsCID.length; i++) { + require(bytes(_catalystIpfsCID[i]).length != 0, "Catalyst: CID cant be empty"); + _setURI(i, _catalystIpfsCID[i]); + highestTierIndex = i; + } + } + + /// @notice Mints a new token, limited to MINTER_ROLE only + /// @param to The address that will own the minted token + /// @param id The token id to mint + /// @param amount The amount to be minted + function mint( + address to, + uint256 id, + uint256 amount + ) external onlyRole(MINTER_ROLE) onlyValidId(id) { + _mint(to, id, amount, ""); + } + + /// @notice Mints a batch of tokens, limited to MINTER_ROLE only + /// @param to The address that will own the minted tokens + /// @param ids The token ids to mint + /// @param amounts The amounts to be minted per token id + function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts + ) external onlyRole(MINTER_ROLE) { + for (uint256 i = 0; i < ids.length; i++) { + require(ids[i] > 0 && ids[i] <= highestTierIndex, "Catalyst: invalid catalyst id"); + } + _mintBatch(to, ids, amounts, ""); + } + + /// @notice Burns a specified amount of tokens from a specific address + /// @param account The address to burn from + /// @param id The token id to burn + /// @param amount The amount to be burned + function burnFrom( + address account, + uint256 id, + uint256 amount + ) external onlyRole(BURNER_ROLE) { + _burn(account, id, amount); + } + + /// @notice Burns a batch of tokens from a specific address + /// @param account The address to burn from + /// @param ids The token ids to burn + /// @param amounts The amounts to be burned + function burnBatchFrom( + address account, + uint256[] memory ids, + uint256[] memory amounts + ) external onlyRole(BURNER_ROLE) { + _burnBatch(account, ids, amounts); + } + + /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only + /// @param ipfsCID The IPFS content identifiers for the catalyst + function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(bytes(ipfsCID).length != 0, "Catalyst: CID cant be empty"); + uint256 newCatId = ++highestTierIndex; + ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID); + emit NewCatalystTypeAdded(newCatId); + } + + /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only + /// @dev Change the address of the trusted forwarder for meta-TX + /// @param trustedForwarder The new trustedForwarder + function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(trustedForwarder != address(0), "Catalyst: Zero address"); + _setTrustedForwarder(trustedForwarder); + } + + /// @notice Set a new URI for specific tokenid + /// @param tokenId The token id to set URI for + /// @param metadataHash The new URI + function setMetadataHash(uint256 tokenId, string memory metadataHash) + external + onlyRole(DEFAULT_ADMIN_ROLE) + onlyValidId(tokenId) + { + require(bytes(metadataHash).length != 0, "Catalyst: Metadata hash empty"); + _setURI(tokenId, metadataHash); + } + + /// @notice Set a new base URI + /// @param baseURI The new base URI + function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(bytes(baseURI).length != 0, "Catalyst: URI empty"); + _setBaseURI(baseURI); + emit BaseURISet(baseURI); + } + + /// @notice returns full token URI, including baseURI and token metadata URI + /// @param tokenId The token id to get URI for + /// @return tokenURI the URI of the token + function uri(uint256 tokenId) + public + view + override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable) + returns (string memory) + { + return ERC1155URIStorageUpgradeable.uri(tokenId); + } + + /// @dev Needed for meta transactions (see EIP-2771) + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + /// @dev Needed for meta transactions (see EIP-2771) + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } + + /// @dev Sets `baseURI` as the `_baseURI` for all tokens + function _setBaseURI(string memory baseURI) internal virtual override { + super._setBaseURI(baseURI); + emit BaseURISet(baseURI); + } + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param value amount of token transfered. + /// @param data additional data accompanying the transfer. + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 value, + bytes memory data + ) public override onlyAllowedOperator(from) { + super._safeTransferFrom(from, to, id, value, data); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @dev call data should be optimized to order ids so packedBalance can be used efficiently. + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param values amount of each token type transfered. + /// @param data additional data accompanying the transfer. + function safeBatchTransferFrom( + address from, + address to, + uint256[] memory ids, + uint256[] memory values, + bytes memory data + ) public override onlyAllowedOperator(from) { + super._safeBatchTransferFrom(from, to, ids, values, data); + } + + /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens. + /// @param operator address which will be granted rights to transfer all tokens of the caller. + /// @param approved whether to approve or revoke + function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { + super._setApprovalForAll(_msgSender(), operator, approved); + } + + function _beforeTokenTransfer( + address operator, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) { + super._beforeTokenTransfer(operator, from, to, ids, amounts, data); + } + + /// @notice Query if a contract implements interface `id`. + /// @param interfaceId the interface identifier, as specified in ERC-165. + /// @return `true` if the contract implements `interfaceId`. + function supportsInterface(bytes4 interfaceId) + public + view + override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of OpenSea. Can only be called by admin. + /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list. + /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe. + /// @param subscribe bool to signify subscription "true"" or to copy the list "false". + function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) + external + onlyRole(DEFAULT_ADMIN_ROLE) + { + require(subscriptionOrRegistrantToCopy != address(0), "Catalyst: Zero address"); + _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe); + } + + /// @notice sets filter registry address + /// @param registry the address of the registry + function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) { + require(registry != address(0), "Catalyst: Zero address"); + OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry); + emit OperatorRegistrySet(registry); + } + + uint256[49] private __gap; +} diff --git a/packages/asset/contracts/interfaces/IAsset.sol b/packages/asset/contracts/interfaces/IAsset.sol new file mode 100644 index 0000000000..bc0bed29d2 --- /dev/null +++ b/packages/asset/contracts/interfaces/IAsset.sol @@ -0,0 +1,77 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +/// @title Asset interface +/// @author The Sandbox +interface IAsset { + // AssetData reflects the asset tokenId structure + // Refer to TokenIdUtils.sol + struct AssetData { + uint256 tokenId; + address creator; + uint256 amount; + uint8 tier; + uint16 creatorNonce; + bool revealed; + string metadataHash; + bool bridged; + } + + event TrustedForwarderChanged(address indexed newTrustedForwarderAddress); + + /// @notice Mint new tokens + /// @dev Only callable by the minter role + /// @param to The address of the recipient + /// @param id The id of the token to mint + /// @param amount The amount of the token to mint + /// @param metadataHash The metadata hash of the token to mint + function mint( + address to, + uint256 id, + uint256 amount, + string memory metadataHash + ) external; + + /// @notice Mint new tokens with catalyst tier chosen by the creator + /// @dev Only callable by the minter role + /// @param to The address of the recipient + /// @param ids The ids of the tokens to mint + /// @param amounts The amounts of the tokens to mint + /// @param metadataHashes The metadata hashes of the tokens to mint + function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts, + string[] memory metadataHashes + ) external; + + /// @notice Burn a token from a given account + /// @dev Only the minter role can burn tokens + /// @dev This function was added with token recycling and bridging in mind but may have other use cases + /// @param account The account to burn tokens from + /// @param id The token id to burn + /// @param amount The amount of tokens to burn + function burnFrom( + address account, + uint256 id, + uint256 amount + ) external; + + /// @notice Burn a batch of tokens from a given account + /// @dev Only the minter role can burn tokens + /// @dev This function was added with token recycling and bridging in mind but may have other use cases + /// @dev The length of the ids and amounts arrays must be the same + /// @param account The account to burn tokens from + /// @param ids An array of token ids to burn + /// @param amounts An array of amounts of tokens to burn + function burnBatchFrom( + address account, + uint256[] memory ids, + uint256[] memory amounts + ) external; + + /// @notice returns the tokenId associated with provided metadata hash + /// @param metadataHash The metadata hash to get tokenId for + /// @return tokenId the tokenId associated with the metadata hash + function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256 tokenId); +} diff --git a/packages/asset/contracts/interfaces/IAssetCreate.sol b/packages/asset/contracts/interfaces/IAssetCreate.sol new file mode 100644 index 0000000000..75b83f3e1f --- /dev/null +++ b/packages/asset/contracts/interfaces/IAssetCreate.sol @@ -0,0 +1,32 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +/// @title AssetCreate interface +/// @author The Sandbox +interface IAssetCreate { + event TrustedForwarderChanged(address indexed newTrustedForwarderAddress); + event AssetMinted( + address indexed creator, + uint256 tokenId, + uint16 tier, + uint256 amount, + string metadataHash, + bool revealed + ); + event SpecialAssetMinted( + address indexed creator, + uint256 tokenId, + uint16 tier, + uint256 amount, + string metadataHash, + bool revealed + ); + event AssetBatchMinted( + address indexed creator, + uint256[] tokenIds, + uint8[] tiers, + uint256[] amounts, + string[] metadataHashes, + bool[] revealed + ); +} diff --git a/packages/asset/contracts/interfaces/IAssetReveal.sol b/packages/asset/contracts/interfaces/IAssetReveal.sol new file mode 100644 index 0000000000..0f75a8aa0c --- /dev/null +++ b/packages/asset/contracts/interfaces/IAssetReveal.sol @@ -0,0 +1,24 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +/// @title AssetReveal interface +/// @author The Sandbox +interface IAssetReveal { + event TrustedForwarderChanged(address indexed newTrustedForwarderAddress); + event AssetRevealBurn(address indexed revealer, uint256 unrevealedTokenId, uint256 amount); + event AssetRevealBatchBurn(address indexed revealer, uint256[] unrevealedTokenIds, uint256[] amounts); + event AssetRevealMint( + address indexed recipient, + uint256 unrevealedTokenId, + uint256[] amounts, + uint256[] newTokenIds, + bytes32[] revealHashes + ); + event AssetRevealBatchMint( + address indexed recipient, + uint256[] unrevealedTokenIds, + uint256[][] amounts, + uint256[][] newTokenIds, + bytes32[][] revealHashes + ); +} diff --git a/packages/asset/contracts/interfaces/ICatalyst.sol b/packages/asset/contracts/interfaces/ICatalyst.sol new file mode 100644 index 0000000000..eb1d3e564e --- /dev/null +++ b/packages/asset/contracts/interfaces/ICatalyst.sol @@ -0,0 +1,65 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +interface ICatalyst { + enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC} + + event TrustedForwarderChanged(address indexed newTrustedForwarderAddress); + event NewCatalystTypeAdded(uint256 catalystId); + event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount); + event BaseURISet(string baseURI); + event OperatorRegistrySet(address indexed registry); + + /// @notice Mints a new token, limited to MINTER_ROLE only + /// @param to The address that will own the minted token + /// @param id The token id to mint + /// @param amount The amount to be minted + function mint( + address to, + uint256 id, + uint256 amount + ) external; + + /// @notice Mints a batch of tokens, limited to MINTER_ROLE only + /// @param to The address that will own the minted tokens + /// @param ids The token ids to mint + /// @param amounts The amounts to be minted per token id + function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts + ) external; + + /// @notice Burns a specified amount of tokens from a specific address + /// @param account The address to burn from + /// @param id The token id to burn + /// @param amount The amount to be burned + function burnFrom( + address account, + uint256 id, + uint256 amount + ) external; + + /// @notice Burns a batch of tokens from a specific address + /// @param account The address to burn from + /// @param ids The token ids to burn + /// @param amounts The amounts to be burned + function burnBatchFrom( + address account, + uint256[] memory ids, + uint256[] memory amounts + ) external; + + /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only + /// @param ipfsCID The royalty bps for the catalyst + function addNewCatalystType(string memory ipfsCID) external; + + /// @notice Set a new URI for specific tokenid + /// @param tokenId The token id to set URI for + /// @param metadataHash The new URI + function setMetadataHash(uint256 tokenId, string memory metadataHash) external; + + /// @notice Set a new base URI + /// @param baseURI The new base URI + function setBaseURI(string memory baseURI) external; +} diff --git a/packages/asset/contracts/interfaces/ITokenUtils.sol b/packages/asset/contracts/interfaces/ITokenUtils.sol new file mode 100644 index 0000000000..37b75e9074 --- /dev/null +++ b/packages/asset/contracts/interfaces/ITokenUtils.sol @@ -0,0 +1,38 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +import {IRoyaltyUGC} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol"; + +/// @title TokenUtils interface +/// @author The Sandbox +interface ITokenUtils is IRoyaltyUGC { + /// @notice Extracts the tier from a given token id + /// @param tokenId The token id to extract the tier from + /// @return tier The asset tier, determined by the catalyst used to create it + function getTier(uint256 tokenId) external pure returns (uint8 tier); + + /// @notice Extracts the revealed flag from a given token id + /// @param tokenId The token id to extract the revealed flag from + /// @return revealed Whether the asset is revealed or not + function isRevealed(uint256 tokenId) external pure returns (bool revealed); + + /// @notice Extracts the asset nonce from a given token id + /// @param tokenId The token id to extract the asset nonce from + /// @return creatorNonce The asset creator nonce + function getCreatorNonce(uint256 tokenId) external pure returns (uint16 creatorNonce); + + /// @notice Extracts the abilities and enhancements hash from a given token id + /// @param tokenId The token id to extract reveal nonce from + /// @return revealNonce The reveal nonce of the asset + function getRevealNonce(uint256 tokenId) external pure returns (uint16 revealNonce); + + /// @notice Extracts the bridged flag from a given token id + /// @param tokenId The token id to extract the bridged flag from + /// @return bridged Whether the asset is bridged or not + function isBridged(uint256 tokenId) external pure returns (bool bridged); + + /// @notice Extracts the creator address from a given token id + /// @param tokenId The token id to extract the creator address from + /// @return creator The asset creator address + function getCreatorAddress(uint256 tokenId) external pure returns (address creator); +} diff --git a/packages/asset/contracts/libraries/TokenIdUtils.sol b/packages/asset/contracts/libraries/TokenIdUtils.sol new file mode 100644 index 0000000000..946ea1bf47 --- /dev/null +++ b/packages/asset/contracts/libraries/TokenIdUtils.sol @@ -0,0 +1,115 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IAsset} from "../interfaces/IAsset.sol"; + +/// @title TokenIdUtils library +/// @author The Sandbox +/// @notice Contains utility functions for token ids +library TokenIdUtils { + // Layer masks + uint256 public constant TIER_MASK = 0xFF; + uint256 public constant NONCE_MASK = 0xFFFF; + uint256 public constant REVEAL_NONCE_MASK = 0xFFFF; + uint256 public constant BRIDGED_MASK = 0x1; + + // Bit shifts + uint256 public constant CREATOR_SHIFT = 0; + uint256 public constant TIER_SHIFT = 160; + uint256 public constant NONCE_SHIFT = 168; + uint256 public constant REVEAL_NONCE_SHIFT = 184; + uint256 public constant BRIDGED_SHIFT = 200; + + /// @notice Generates a token id for a given asset + /// @dev The token id is generated by concatenating the following fields: + /// @dev creator address, tier, creator nonce, reveal nonce and bridged boolean + /// @dev The first 160 bits are the creator address + /// @dev The next 8 bits are the tier + /// @dev The next 16 bits are the creator nonce + /// @dev The next 16 bits are for reveal nonce. + /// @dev The last bit is for bridged boolean + /// @param creator The address of the creator of the asset + /// @param tier The tier of the asset determined by the catalyst used to create it + /// @param creatorNonce The nonce of the asset creator + /// @param revealNonce The reveal nonce of the asset + /// @param bridged Whether the asset is bridged or not + /// @return tokenId The generated token id + function generateTokenId( + address creator, + uint8 tier, + uint16 creatorNonce, + uint16 revealNonce, + bool bridged + ) internal pure returns (uint256 tokenId) { + uint160 creatorAddress = uint160(creator); + + tokenId = tokenId = + uint256(creatorAddress) | + (uint256(tier) << TIER_SHIFT) | + (uint256(creatorNonce) << NONCE_SHIFT) | + (uint256(revealNonce) << REVEAL_NONCE_SHIFT) | + (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT); + + return tokenId; + } + + /// @notice Extracts the creator address from a given token id + /// @param tokenId The token id to extract the creator address from + /// @return creator The asset creator address + function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) { + creator = address(uint160(tokenId)); + return creator; + } + + /// @notice Extracts the tier from a given token id + /// @param tokenId The token id to extract the tier from + /// @return tier The asset tier, determined by the catalyst used to create it + function getTier(uint256 tokenId) internal pure returns (uint8 tier) { + tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK); + return tier; + } + + /// @notice Extracts the revealed flag from a given token id + /// @param tokenId The token id to extract the revealed flag from + /// @return isRevealed Whether the asset is revealed or not + function isRevealed(uint256 tokenId) internal pure returns (bool) { + uint16 revealNonce = getRevealNonce(tokenId); + return revealNonce != 0; + } + + /// @notice Extracts the asset nonce from a given token id + /// @param tokenId The token id to extract the asset nonce from + /// @return creatorNonce The asset creator nonce + function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) { + uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK); + return creatorNonce; + } + + /// @notice Extracts the abilities and enhancements hash from a given token id + /// @param tokenId The token id to extract reveal nonce from + /// @return revealNonce The reveal nonce of the asset + function getRevealNonce(uint256 tokenId) internal pure returns (uint16) { + uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK); + return revealNonce; + } + + /// @notice Extracts the bridged flag from a given token id + /// @param tokenId The token id to extract the bridged flag from + /// @return bridged Whether the asset is bridged or not + function isBridged(uint256 tokenId) internal pure returns (bool) { + bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1; + return bridged; + } + + /// @notice Extracts the asset data from a given token id + /// @dev Created to limit the number of functions that need to be called when revealing an asset + /// @param tokenId The token id to extract the asset data from + /// @return data The asset data struct + function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) { + data.creator = getCreatorAddress(tokenId); + data.tier = getTier(tokenId); + data.revealed = isRevealed(tokenId); + data.creatorNonce = getCreatorNonce(tokenId); + data.bridged = isBridged(tokenId); + } +} diff --git a/packages/asset/contracts/mock/FallBackRegistry.sol b/packages/asset/contracts/mock/FallBackRegistry.sol new file mode 100644 index 0000000000..7b67fc3852 --- /dev/null +++ b/packages/asset/contracts/mock/FallBackRegistry.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + FallbackRegistry +} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/FallbackRegistry.sol"; diff --git a/packages/asset/contracts/mock/MockAsset.sol b/packages/asset/contracts/mock/MockAsset.sol new file mode 100644 index 0000000000..7c17db6a59 --- /dev/null +++ b/packages/asset/contracts/mock/MockAsset.sol @@ -0,0 +1,44 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +// mock the asset contract to test the _msgData() function + +import {Asset} from "../Asset.sol"; +import { + IOperatorFilterRegistry +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol"; + +contract MockAsset is Asset { + /// @notice sets registry and subscribe to subscription + /// @param registry address of registry + /// @param subscription address to subscribe + function setRegistryAndSubscribe(address registry, address subscription) external { + _setOperatorFilterRegistry(registry); + IOperatorFilterRegistry operatorFilterRegistry = _getOperatorFilterRegistry(); + operatorFilterRegistry = IOperatorFilterRegistry(registry); + operatorFilterRegistry.registerAndSubscribe(address(this), subscription); + } + + /// @notice Mint new tokens with out minter role + /// @param to The address of the recipient + /// @param id The id of the token to mint + /// @param amount The amount of the token to mint + function mintWithoutMinterRole( + address to, + uint256 id, + uint256 amount + ) external { + _mint(to, id, amount, ""); + } + + /// @notice set approval for asset transfer without filtering + /// @param operator operator to be approved + /// @param approved bool value for giving (true) and canceling (false) approval + function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual { + _setApprovalForAll(_msgSender(), operator, approved); + } + + function msgData() external view returns (bytes memory) { + return _msgData(); + } +} diff --git a/packages/asset/contracts/mock/MockAssetCreate.sol b/packages/asset/contracts/mock/MockAssetCreate.sol new file mode 100644 index 0000000000..1a2e52f522 --- /dev/null +++ b/packages/asset/contracts/mock/MockAssetCreate.sol @@ -0,0 +1,12 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +// mock the asset contract to test the _msgData() function to satisfy the coverage + +import {AssetCreate} from "../AssetCreate.sol"; + +contract MockAssetCreate is AssetCreate { + function msgData() external view returns (bytes memory) { + return _msgData(); + } +} diff --git a/packages/asset/contracts/mock/MockAssetReveal.sol b/packages/asset/contracts/mock/MockAssetReveal.sol new file mode 100644 index 0000000000..4107ac5e89 --- /dev/null +++ b/packages/asset/contracts/mock/MockAssetReveal.sol @@ -0,0 +1,12 @@ +//SPDX-License-Identifier: MIT +pragma solidity 0.8.18; + +// mock the asset contract to test the _msgData() function to satisfy the coverage + +import {AssetReveal} from "../AssetReveal.sol"; + +contract MockAssetReveal is AssetReveal { + function msgData() external view returns (bytes memory) { + return _msgData(); + } +} diff --git a/packages/asset/contracts/mock/MockCatalyst.sol b/packages/asset/contracts/mock/MockCatalyst.sol new file mode 100644 index 0000000000..acbd616904 --- /dev/null +++ b/packages/asset/contracts/mock/MockCatalyst.sol @@ -0,0 +1,36 @@ +//SPDX-License-Identifier: MIT + +pragma solidity 0.8.18; + +import {Catalyst, IOperatorFilterRegistry} from "../Catalyst.sol"; + +contract MockCatalyst is Catalyst { + /// @notice sets registry and subscribe to subscription + /// @param registry address of registry + /// @param subscription address to subscribe + function setRegistryAndSubscribe(address registry, address subscription) external { + _setOperatorFilterRegistry(registry); + IOperatorFilterRegistry operatorFilterRegistry = _getOperatorFilterRegistry(); + operatorFilterRegistry = IOperatorFilterRegistry(registry); + operatorFilterRegistry.registerAndSubscribe(address(this), subscription); + } + + /// @notice Mint new tokens with out minter role + /// @param to The address of the recipient + /// @param id The id of the token to mint + /// @param amount The amount of the token to mint + function mintWithoutMinterRole( + address to, + uint256 id, + uint256 amount + ) external { + _mint(to, id, amount, ""); + } + + /// @notice set approval for asset transfer without filteration + /// @param operator operator to be approved + /// @param approved bool value for giving (true) and canceling (false) approval + function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual { + _setApprovalForAll(_msgSender(), operator, approved); + } +} diff --git a/packages/asset/contracts/mock/MockMarketPlace1.sol b/packages/asset/contracts/mock/MockMarketPlace1.sol new file mode 100644 index 0000000000..33bc8bb1fe --- /dev/null +++ b/packages/asset/contracts/mock/MockMarketPlace1.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + MockERC1155MarketPlace1 +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol"; diff --git a/packages/asset/contracts/mock/MockMarketPlace2.sol b/packages/asset/contracts/mock/MockMarketPlace2.sol new file mode 100644 index 0000000000..f443a25866 --- /dev/null +++ b/packages/asset/contracts/mock/MockMarketPlace2.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + MockERC1155MarketPlace2 +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol"; diff --git a/packages/asset/contracts/mock/MockMarketPlace3.sol b/packages/asset/contracts/mock/MockMarketPlace3.sol new file mode 100644 index 0000000000..053ebcd444 --- /dev/null +++ b/packages/asset/contracts/mock/MockMarketPlace3.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + MockERC1155MarketPlace3 +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol"; diff --git a/packages/asset/contracts/mock/MockMarketPlace4.sol b/packages/asset/contracts/mock/MockMarketPlace4.sol new file mode 100644 index 0000000000..5d1ca3fcd1 --- /dev/null +++ b/packages/asset/contracts/mock/MockMarketPlace4.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + MockERC1155MarketPlace4 +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol"; diff --git a/packages/asset/contracts/mock/MockMarketplace.sol b/packages/asset/contracts/mock/MockMarketplace.sol new file mode 100644 index 0000000000..342949ded1 --- /dev/null +++ b/packages/asset/contracts/mock/MockMarketplace.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + MockMarketplace +} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/MockMarketplace.sol"; diff --git a/packages/asset/contracts/mock/MockMinter.sol b/packages/asset/contracts/mock/MockMinter.sol new file mode 100644 index 0000000000..dfade230e6 --- /dev/null +++ b/packages/asset/contracts/mock/MockMinter.sol @@ -0,0 +1,37 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IAsset} from "../interfaces/IAsset.sol"; +import {TokenIdUtils} from "../libraries/TokenIdUtils.sol"; + +contract MockMinter { + using TokenIdUtils for uint256; + + IAsset public assetContract; + + mapping(address => uint16) public creatorNonces; + + event Minted(uint256 tokenId, uint256 amount); + + constructor(address _assetContract) { + assetContract = IAsset(_assetContract); + } + + /// @dev Mints a specified number of unrevealed copies of specific tier + function mintAsset( + address recipient, + uint256 amount, + uint8 tier, + bool revealed, + string calldata metadataHash + ) public { + // increment nonce + unchecked {creatorNonces[msg.sender]++;} + // get current creator nonce + uint16 creatorNonce = creatorNonces[msg.sender]; + uint256 tokenId = TokenIdUtils.generateTokenId(msg.sender, tier, creatorNonce, revealed ? 1 : 0, false); + + assetContract.mint(recipient, tokenId, amount, metadataHash); + emit Minted(tokenId, amount); + } +} diff --git a/packages/asset/contracts/mock/MockOperatorFilterRegistry.sol b/packages/asset/contracts/mock/MockOperatorFilterRegistry.sol new file mode 100644 index 0000000000..4de5e67329 --- /dev/null +++ b/packages/asset/contracts/mock/MockOperatorFilterRegistry.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + MockOperatorFilterRegistry +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol"; diff --git a/packages/asset/contracts/mock/MockOperatorFilterSubscription.sol b/packages/asset/contracts/mock/MockOperatorFilterSubscription.sol new file mode 100644 index 0000000000..6eb9b445f1 --- /dev/null +++ b/packages/asset/contracts/mock/MockOperatorFilterSubscription.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + MockOperatorFilterSubscription +} from "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol"; diff --git a/packages/asset/contracts/mock/MockTrustedForwarder.sol b/packages/asset/contracts/mock/MockTrustedForwarder.sol new file mode 100644 index 0000000000..7048aa7bac --- /dev/null +++ b/packages/asset/contracts/mock/MockTrustedForwarder.sol @@ -0,0 +1,4 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {MockTrustedForwarder} from "@sandbox-smart-contracts/dependency-metatx/contracts/test/MockTrustedForwarder.sol"; diff --git a/packages/asset/contracts/mock/RoyaltyEngineV1.sol b/packages/asset/contracts/mock/RoyaltyEngineV1.sol new file mode 100644 index 0000000000..9ec53a0c1a --- /dev/null +++ b/packages/asset/contracts/mock/RoyaltyEngineV1.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + RoyaltyEngineV1 +} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol"; diff --git a/packages/asset/contracts/mock/RoyaltyManager.sol b/packages/asset/contracts/mock/RoyaltyManager.sol new file mode 100644 index 0000000000..6540c3bf65 --- /dev/null +++ b/packages/asset/contracts/mock/RoyaltyManager.sol @@ -0,0 +1,3 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {RoyaltyManager} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol"; diff --git a/packages/asset/contracts/mock/RoyaltyRegistry.sol b/packages/asset/contracts/mock/RoyaltyRegistry.sol new file mode 100644 index 0000000000..43d4c1aa69 --- /dev/null +++ b/packages/asset/contracts/mock/RoyaltyRegistry.sol @@ -0,0 +1,5 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + RoyaltyRegistry +} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol"; diff --git a/packages/asset/contracts/mock/RoyaltySplitter.sol b/packages/asset/contracts/mock/RoyaltySplitter.sol new file mode 100644 index 0000000000..972fd5b62a --- /dev/null +++ b/packages/asset/contracts/mock/RoyaltySplitter.sol @@ -0,0 +1,8 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {RoyaltySplitter} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol"; + +/* solhint-disable-next-line no-empty-blocks*/ +contract MockSplitter is RoyaltySplitter { + +} diff --git a/packages/asset/contracts/mock/TestERC20.sol b/packages/asset/contracts/mock/TestERC20.sol new file mode 100644 index 0000000000..2efaa86d19 --- /dev/null +++ b/packages/asset/contracts/mock/TestERC20.sol @@ -0,0 +1,3 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {TestERC20} from "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC20.sol"; diff --git a/packages/asset/contracts/mock/TokenIdUtilsWrapped.sol b/packages/asset/contracts/mock/TokenIdUtilsWrapped.sol new file mode 100644 index 0000000000..96c193d643 --- /dev/null +++ b/packages/asset/contracts/mock/TokenIdUtilsWrapped.sol @@ -0,0 +1,77 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {TokenIdUtils} from "../libraries/TokenIdUtils.sol"; +import {IAsset} from "../interfaces/IAsset.sol"; + +contract TokenIdUtilsWrapped { + function generateTokenId( + address creator, + uint8 tier, + uint16 creatorNonce, + uint16 revealNonce, + bool bridged + ) public pure returns (uint256 tokenId) { + return TokenIdUtils.generateTokenId(creator, tier, creatorNonce, revealNonce, bridged); + } + + function getCreatorAddress(uint256 tokenId) public pure returns (address creator) { + return TokenIdUtils.getCreatorAddress(tokenId); + } + + function getTier(uint256 tokenId) public pure returns (uint8 tier) { + return TokenIdUtils.getTier(tokenId); + } + + function getCreatorNonce(uint256 tokenId) public pure returns (uint16 creatorNonce) { + return TokenIdUtils.getCreatorNonce(tokenId); + } + + function isRevealed(uint256 tokenId) public pure returns (bool) { + return TokenIdUtils.isRevealed(tokenId); + } + + function getRevealNonce(uint256 tokenId) public pure returns (uint16) { + return TokenIdUtils.getRevealNonce(tokenId); + } + + function isBridged(uint256 tokenId) public pure returns (bool) { + return TokenIdUtils.isBridged(tokenId); + } + + function getData(uint256 tokenId) public pure returns (IAsset.AssetData memory data) { + return TokenIdUtils.getData(tokenId); + } + + function TIER_MASK() public pure returns (uint256) { + return TokenIdUtils.TIER_MASK; + } + + function NONCE_MASK() public pure returns (uint256) { + return TokenIdUtils.NONCE_MASK; + } + + function REVEAL_NONCE_MASK() public pure returns (uint256) { + return TokenIdUtils.REVEAL_NONCE_MASK; + } + + function BRIDGED_MASK() public pure returns (uint256) { + return TokenIdUtils.BRIDGED_MASK; + } + + function TIER_SHIFT() public pure returns (uint256) { + return TokenIdUtils.TIER_SHIFT; + } + + function NONCE_SHIFT() public pure returns (uint256) { + return TokenIdUtils.NONCE_SHIFT; + } + + function REVEAL_NONCE_SHIFT() public pure returns (uint256) { + return TokenIdUtils.REVEAL_NONCE_SHIFT; + } + + function BRIDGED_SHIFT() public pure returns (uint256) { + return TokenIdUtils.BRIDGED_SHIFT; + } +} diff --git a/packages/asset/data/constants.ts b/packages/asset/data/constants.ts new file mode 100644 index 0000000000..58360ec155 --- /dev/null +++ b/packages/asset/data/constants.ts @@ -0,0 +1,15 @@ +export const CATALYST_BASE_URI = 'ipfs://'; +export const CATALYST_IPFS_CID_PER_TIER = [ + 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', + 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', + 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', + 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', + 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', + 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', + 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', +]; + +export const OPERATOR_FILTER_REGISTRY = + '0x000000000000AAeB6D7670E522A718067333cd4E'; +export const DEFAULT_SUBSCRIPTION = + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'; diff --git a/packages/asset/docs/Asset.md b/packages/asset/docs/Asset.md new file mode 100644 index 0000000000..aede9fb989 --- /dev/null +++ b/packages/asset/docs/Asset.md @@ -0,0 +1,297 @@ +# Asset Contract Documentation + +This is the base Asset L2 contract that serves as an upgradeable, burnable ERC1155 token that includes roles for minting, burning, and administration. It includes extended functionality for managing base and token-specific URIs and maintaining a mapping between IPFS metadata hashes and token IDs. + +## Roles in the Contract + +1. **Minter**: This role can create new tokens using the `mint` or `mintBatch` functions. +2. **Burner**: This role can destroy tokens using the `burnFrom` or `burnBatchFrom` functions. +3. **Admin**: This role has broad administrative permissions including the ability to set URIs and change the trusted forwarder. +4. **Moderator**: This role has the ability to set URIs. + +## Public Variables + +1. `MINTER_ROLE` - A bytes32 value representing the role that can mint new tokens. +2. `BURNER_ROLE` - A bytes32 value representing the role that can burn tokens. +3. `MODERATOR_ROLE` - A bytes32 value representing the role that can set URIs. +4. `hashUsed` - A mapping from string metadata hashes to uint256 token IDs. + +## Functions + +### initialize + +```solidity +function initialize( + address forwarder, + address assetAdmin, + string memory baseUri + address commonSubscription, + address _manager +) external initializer +``` + +Initializes the contract with the specified parameters at the time of deployment. + +Parameters: + +- `forwarder` - The trusted forwarder for meta-transactions. +- `assetAdmin` - The address that will be granted the DEFAULT_ADMIN_ROLE. +- `baseUri` - The base URI for the contract. +- `commonSubscription` - the address of the subscription for operator filter +- `_manager` - the address of royalty manager contract + +### mint + +```solidity +function mint( + address to, + uint256 id, + uint256 amount, + string memory metadataHash +) external onlyRole(MINTER_ROLE) +``` + +Creates a given amount of a new token with a specified ID and associates a metadata hash with it. + +Parameters: + +- `to` - The address that will receive the newly minted tokens. +- `id` - The ID for the new tokens. +- `amount` - The number of new tokens to create. +- `metadataHash` - The IPFS metadata hash to associate with the new tokens. + +### mintBatch + +```solidity +function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts, + string[] memory metadataHashes +) external onlyRole(MINTER_ROLE) +``` + +Creates a batch of new tokens with the provided IDs and amounts and associates metadata hashes with them. + +Parameters: + +- `to` - The address that will receive the newly minted tokens. +- `ids` - An array of IDs for the new tokens. +- `amounts` - An array of the number of new tokens to create for each ID. +- `metadataHashes` - An array of IPFS metadata hashes to associate with the new tokens. + +### burnFrom + +```solidity +function burnFrom( + address account, + uint256 id, + uint256 amount +) external onlyRole(BURNER_ROLE) +``` + +Destroys a given amount of a specific token from an account. + +Parameters: + +- `account` - The account from which tokens will be burned. +- `id` - The ID of the token to be burned. +- `amount` - The number of tokens to burn. + +### burnBatchFrom + +```solidity +function burnBatchFrom( + address account, + uint256[] memory ids, + uint256[] memory amounts +) external onlyRole(BURNER_ROLE) +``` + +Destroys a batch of tokens from an account. + +Parameters: + +- `account` - The account from which tokens will be burned. +- `ids` - An array of IDs for the tokens to be burned. +- `amounts` - An array of the number of tokens to burn for each ID. + +### setTokenURI + +```solidity +function setTokenURI(uint256 tokenId, string memory metadata) external +``` + +Sets a new URI for a specific token, only available to MODERATOR_ROLE. + +Parameters: + +- `tokenId` - The ID of the token to set the URI for. +- `metadata` - The new URI for the token's metadata. + +### setBaseURI + +```solidity +function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) +``` + +Sets a new base URI for the contract. + +Parameters: + +- `baseURI` - The new base URI. + +### uri + +```solidity +function uri(uint256 tokenId) public view override returns (string memory) +``` + +Returns the full URI for a specific token, including the base URI and the token-specific metadata URI. + +Parameters: + +- `tokenId` - The ID of the token to get the URI for. + +### getTokenIdByMetadataHash + +```solidity +function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) +``` + +Returns the token ID associated with a specific metadata hash. + +Parameters: + +- `metadataHash` - The metadata hash to query the token ID for. + +### setTrustedForwarder + +```solidity +function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) +``` + +Sets a new trusted forwarder for meta-transactions. + +Parameters: + +- `trustedForwarder` - The new trusted forwarder. + +### setTokenRoyalties + +```solidity +function setTokenRoyalties( + uint256 tokenId, + address payable recipient, + address creator +) external override onlyRole(DEFAULT_ADMIN_ROLE) +``` + +Sets token royalty i.e. the creator splitter address as EIP2981 royalty recipient. deploys a splitter if there is none deployed for a creator. Only admin can call it. + +Parameters: + +- `tokenId` - the id of the token for which the royalty is set. +- `recipient` - the royalty recipient wallet. +- `creator` - the creator of the token. + +### getCreatorAddress + +```solidity +function getCreatorAddress(uint256 tokenId) external pure returns (address creator) +``` + +Returns the creator for a token. + +Parameters: + +- `tokenId` - the id of the token. + +### getTier + +```solidity +function getTier(uint256 tokenId) external pure returns (uint8 tier) +``` + +Returns the tier for a token. + +Parameters: + +- `tokenId` - the id of the token. + +### isRevealed + +```solidity +function isRevealed(uint256 tokenId) external pure returns (bool) +``` + +Returns bool representing if the token has been revealed or not. + +Parameters: + +- `tokenId` - the id of the token. + +### getCreatorNonce + +```solidity +function getCreatorNonce(uint256 tokenId) external pure returns (uint16) +``` + +Returns the creator's nonce using which the token was minted. + +Parameters: + +- `tokenId` - the id of the token. + +### getRevealNonce + +```solidity +function getRevealNonce(uint256 tokenId) external pure returns (uint16) +``` + +Returns the reveal nonce of the token. + +Parameters: + +- `tokenId` - the id of the token. + +### isBridged + +```solidity +function isBridged(uint256 tokenId) external pure returns (bool) +``` + +Returns bool representing if the token has been bridged. + +Parameters: + +- `tokenId` - the id of the token. + +### registerAndSubscribe + +```solidity +function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) + external + onlyRole(DEFAULT_ADMIN_ROLE) +``` + +Used to register and subscribe on the operator filter registry of OpenSea + +Parameters: + +- `subscriptionOrRegistrantToCopy` - the address of the subscription. +- `subscribe` - the bool value representing to subscribe or not. + +### setOperatorRegistry + +```solidity +function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) +``` + +Used to the address of the operator filter registry + +Parameters: + +- `registry` - the address of the operator filter registry. + +This document is essential for developers who need to understand or contribute to the code in the future. Please make sure to keep it updated and as detailed as possible. diff --git a/packages/asset/docs/AssetCreate.md b/packages/asset/docs/AssetCreate.md new file mode 100644 index 0000000000..672df23a39 --- /dev/null +++ b/packages/asset/docs/AssetCreate.md @@ -0,0 +1,252 @@ +# Asset Create Contract Documentation + +This document serves as comprehensive documentation for the AssetCreate contract, which is responsible for creating new assets in The Sandbox ecosystem. It outlines the contract's roles, public variables, and functions, providing details on their purposes, parameters, and access controls. + +## Roles in the Contract + +1. **DEFAULT_ADMIN_ROLE**: The role with broad administrative permissions, including setting URIs and changing the trusted forwarder. +2. **SPECIAL_MINTER_ROLE**: The special minter role with permission to create special assets like TSB exclusive tokens. +3. **PAUSER_ROLE**: The role with permission to pause the contract. + +## Public Variables + +1. `assetContract`: The address of the asset contract. +2. `catalystContract`: The address of the catalyst contract. +3. `authValidator`: The address of the AuthSuperValidator contract. +4. `creatorNonces`: A public mapping from address to uint16, representing the creator's nonce. The nonce is incremented every time a creator mints a new token. +5. `signatureNonces`: A public mapping from address to uint16, representing the signature's nonce. The nonce is incremented for each signature generated by the address. + +## Functions + +### initialize + +```solidity +function initialize( + string memory name, + string memory version, + address assetContract, + address catalystContract, + address authValidator, + address forwarder, + address defaultAdmin +) external +``` + +Initializes the contract with the specified parameters at the time of deployment. + +Parameters: + +- `name`: The name of the contract. +- `version`: The version of the contract. +- `assetContract`: The address of the asset contract. +- `catalystContract`: The address of the catalyst contract. +- `authValidator`: The address of the AuthSuperValidator contract. +- `forwarder`: The address of the trusted forwarder for meta-transactions. +- `defaultAdmin`: The address that will be granted the DEFAULT_ADMIN_ROLE. + +### createAsset + +```solidity +function createAsset( + bytes memory signature, + uint8 tier, + uint256 amount, + bool revealed, + string calldata metadataHash, + address creator +) external +``` + +Creates a new asset and associates it with the provided metadata hash. The asset is minted to the creator's address. + +Parameters: + +- `signature`: A signature generated by TSB for authentication. +- `tier`: The tier of the asset to mint. +- `amount`: The amount of the asset to mint. +- `revealed`: A boolean indicating whether the asset is revealed or hidden. +- `metadataHash`: The IPFS metadata hash associated with the asset. +- `creator`: The address of the asset creator. + +### createMultipleAssets + +```solidity +function createMultipleAssets( + bytes memory signature, + uint8[] calldata tiers, + uint256[] calldata amounts, + bool[] calldata revealed, + string[] calldata metadataHashes, + address creator +) external +``` + +Creates multiple assets at once and associates them with the provided metadata hashes. The assets are minted to the creator's address. + +Parameters: + +- `signature`: A signature generated by TSB for authentication. +- `tiers`: An array containing the tiers of the assets to mint. +- `amounts`: An array containing the amount of each asset to mint. +- `revealed`: An array of booleans indicating whether each asset is revealed or hidden. +- `metadataHashes`: An array containing the IPFS metadata hashes associated with the assets. +- `creator`: The address of the asset creator. + +### createSpecialAsset + +```solidity +function createSpecialAsset( + bytes memory signature, + uint256 amount, + string calldata metadataHash, + address creator +) external onlyRole(SPECIAL_MINTER_ROLE) +``` + +Creates a special tier 0 TSB exclusive asset and associates it with the provided metadata hash. This function can only be called by the address with the SPECIAL_MINTER_ROLE. +This function mints the assets as revealed. + +Parameters: + +- `signature`: A signature generated by TSB for authentication. +- `amount`: The amount of the asset to mint. +- `metadataHash`: The IPFS metadata hash associated with the asset. +- `creator`: The address of the asset creator. + +### getAssetContract + +```solidity +function getAssetContract() external view returns (address) +``` + +Returns the address of the asset contract. + +### getCatalystContract + +```solidity +function getCatalystContract() external view returns (address) +``` + +Returns the address of the catalyst contract. + +### getAuthValidator + +```solidity +function getAuthValidator() external view returns (address) +``` + +Returns the address of the AuthSuperValidator contract. + +### setTrustedForwarder + +```solidity +function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) +``` + +Sets a new trusted forwarder for meta-transactions. This function is limited to addresses with the DEFAULT_ADMIN_ROLE. + +Parameters: + +- `trustedForwarder`: The new trusted forwarder address. + +## Internal Functions + +### \_hashMint + +```solidity +function _hashMint( + address creator, + uint16 nonce, + uint8 tier, + uint256 amount, + bool revealed, + string calldata metadataHash +) internal view returns (bytes32 digest) +``` + +Creates a hash of the mint data for signature verification. + +Parameters: + +- `creator`: The address of the creator. +- `nonce`: The creator's nonce for the mint operation. +- `tier`: The tier of the asset to mint. +- `amount`: The amount of the asset to mint. +- `revealed`: A boolean indicating whether the asset is revealed or hidden. +- `metadataHash`: The IPFS metadata hash associated with the asset. + +Returns: + +- `digest`: The hash of the mint data. + +### \_hashBatchMint + +```solidity +function _hashBatchMint( + address creator, + uint16 nonce, + uint8[] calldata tiers, + uint256[] calldata amounts, + bool[] calldata revealed, + string[] calldata metadataHashes +) internal view returns (bytes32 digest) +``` + +Creates a hash of the mint batch data for signature verification. + +Parameters: + +- `creator`: The address of the creator. +- `nonce`: The creator's nonce for the mint batch operation. +- `tiers`: An array containing the tiers of the assets to mint. +- `amounts`: An array containing the amount of each asset to mint. +- `revealed`: An array of booleans indicating whether each asset is revealed or hidden. +- `metadataHashes`: An array containing the IPFS metadata hashes associated with the assets. + +Returns: + +- `digest`: The hash of the mint batch data. + +### \_encodeHashes + +```solidity +function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) +``` + +Encodes the hashes of the metadata for signature verification. + +Parameters: + +- `metadataHashes`: An array containing the IPFS metadata hashes associated with the assets. + +Returns: + +- `encodedHashes`: The encoded hashes of the metadata. + +### \_msgSender + +```solidity +function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) +``` + +Internal function to get the message sender address for meta-transactions. + +Returns: + +- `sender`: The address of the sender. + +### \_msgData + +```solidity +function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) +``` + +Internal function to get the message data for meta-transactions. + +Returns: + +- `calldata`: The message data. + + *** + +This documentation provides an overview of the AssetCreate contract and its functionalities. Developers can refer to this document to understand the contract's behavior, its purpose, and the functions available for creating new assets in The Sandbox ecosystem. diff --git a/packages/asset/docs/AssetReveal.md b/packages/asset/docs/AssetReveal.md new file mode 100644 index 0000000000..1be1883464 --- /dev/null +++ b/packages/asset/docs/AssetReveal.md @@ -0,0 +1,362 @@ +# AssetReveal Contract Documentation + +This is a solidity contract designed for managing the revealing of assets linked to previously hidden tokens. It is designed to be used in conjunction with the [Asset](./Asset.md) contract. + +## Roles in the Contract + +1. **DEFAULT_ADMIN_ROLE**: This role has broad administrative permissions, including the ability to set the trusted forwarder. +2. **PAUSER_ROLE**: The role with permission to pause the contract. + +## Public Variables + +1. `REVEAL_TYPEHASH`: The typehash for the reveal function. +2. `BATCH_REVEAL_TYPEHASH`: The typehash for the batch reveal function. +3. `INSTANT_REVEAL_TYPEHASH`: The typehash for the instant reveal function. +4. `trustedForwarder`: The address of the trusted forwarder. + +## Public and External Functions + +### initialize + +```solidity +function initialize( + string memory _name, + string memory _version, + address _assetContract, + address _authValidator, + address _forwarder, + address _defaultAdmin + ) public initializer +``` + +Initializes the contract with the specified parameters at the time of deployment. + +Parameters: + +- `_name` - The name of the contract. +- `_version` - The version of the contract. +- `_assetContract` - The address of the Asset contract. +- `_authValidator` - The address of the AuthValidator contract. +- `_forwarder` - The address of the trusted forwarder. +- `_defaultAdmin` - The address that will be granted the DEFAULT_ADMIN_ROLE. + +### revealBurn + +```solidity +function revealBurn(uint256 tokenId, uint256 amount) external +``` + +Burns an unrevealed tokens and emits an event with details needed by the backend to generate the revealed version of the token. + +Parameters: + +- `tokenId` - The ID of the token to burn. +- `amount` - The amount of the token to burn. + +### revealBurnBatch + +```solidity + function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external +``` + +Burns a batch of unrevealed tokens and emits an event with details needed by the backend to generate the revealed version of the tokens. + +Parameters: + +- `tokenIds` - The IDs of the tokens to burn. +- `amounts` - The amounts of the tokens to burn. + +### revealMint + +```solidity +function revealMint( + bytes memory signature, + uint256 prevTokenId, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) external +``` + +Uses a signature to validate the mint data and the randomly generated metadata for the revealed token. + +Parameters: + +- `signature` - The signature used to validate the mint data. +- `prevTokenId` - The ID of the token that hides the assets to be revealed. +- `amounts` - The amounts of each new token to mint. +- `metadataHashes` - The hashes of the metadata for each new token. +- `revealHashes` - The reveal hashes used for revealing this particular `prevTokenId`. + +### revealBatchMint + +```solidity +function revealBatchMint( + bytes calldata signature, + uint256[] calldata prevTokenIds, + uint256[][] calldata amounts, + string[][] calldata metadataHashes, + bytes32[][] calldata revealHashes + ) external +``` + +Uses a signature to validate the mint data and the randomly generated metadata for the revealed tokens. + +Parameters: + +- `signature` - The signature used to validate the mint data. +- `prevTokenIds` - The IDs of the tokens that hide the assets to be revealed. +- `amounts` - The amounts of each new token to mint for each `prevTokenId`. +- `metadataHashes` - The hashes of the metadata for each new token for each `prevTokenId`. +- `revealHashes` - The reveal hashes used for revealing each particular `prevTokenId`. + +### burnAndReveal + +```solidity +function burnAndReveal( + bytes memory signature, + uint256 prevTokenId, + uint256 burnAmount, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) external +``` + +Burns and reveales a token in a single transaction, only usable for tokens that allow users to choose their revealed abilities. + +Parameters: + +- `signature` - The signature used to validate the mint data. +- `prevTokenId` - The ID of the token that hides the assets to be revealed. +- `burnAmount` - The amount of the token to burn. +- `amounts` - The amounts of each new token to mint. +- `metadataHashes` - The hashes of the metadata for each new token. +- `revealHashes` - The reveal hashes used for revealing this particular `prevTokenId`. + +### revealHashUsed + +```solidity +function revealHashUsed(bytes32 revealHash) external view returns (bool) +``` + +Checks whether a reveal hash has been used before. + +Parameters: + +- `revealHash` - The reveal hash to check. + +### getAssetContract + +```solidity +function getAssetContract() external view returns (address) +``` + +Returns the address of the Asset contract. + +### getAuthValidator + +```solidity +function getAuthValidator() external view returns (address) +``` + +Returns the address of the AuthValidator contract. + +### setTrustedForwarder + +```solidity +function setTrustedForwarder(address _forwarder) external onlyRole(DEFAULT_ADMIN_ROLE) +``` + +Sets the trusted forwarder. + +Parameters: + +- `_forwarder` - The address of the new trusted forwarder. + +## Internal Functions + +### \_revealAsset + +```solidity +function _revealAsset( + uint256 prevTokenId, + string[] calldata metadataHashes, + uint256[] calldata amounts, + bytes32[] calldata revealHashes + ) internal returns (uint256[] memory) +``` + +Generates new tokenIds for the revealed assets and mints them to the end user. + +Parameters: + +- `prevTokenId` - The ID of the token that hides the assets to be revealed. +- `metadataHashes` - The hashes of the metadata for each new token. +- `amounts` - The amounts of each new token to mint. +- `revealHashes` - The reveal hashes used for revealing this particular `prevTokenId`. + +### \_burnAsset + +```solidity +function _burnAsset(uint256 tokenId, uint256 amount) internal +``` + +Verifies the burn request and burns the specified amount of the token. + +Parameters: + +- `tokenId` - The ID of the token to burn. +- `amount` - The amount of the token to burn. + +### \_burnAssetBatch + +```solidity +function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal +``` + +Verifies the burn request and burns the specified amounts of the tokens. + +Parameters: + +- `tokenIds` - The IDs of the tokens to burn. +- `amounts` - The amounts of the tokens to burn. + +### \_verifyBurnData + +```solidity +function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure +``` + +Validates that the token has not been revealed yet and that the amount is greater than 0. + +Parameters: + +- `tokenId` - The ID of the token to burn. +- `amount` - The amount of the token to burn. + +### \_hashInstantReveal + +```solidity +function _hashInstantReveal( + address recipient, + uint256 prevTokenId, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) internal view returns (bytes32 digest) +``` + +Hashes the data for an instant reveal creating digest for EIP712 signature. + +Parameters: + +- `recipient` - The address that will receive the newly minted tokens. +- `prevTokenId` - The ID of the token that hides the assets to be revealed. +- `amounts` - The amounts of each new token to mint. +- `metadataHashes` - The hashes of the metadata for each new token. +- `revealHashes` - The reveal hashes used for revealing this particular `prevTokenId`. + +### \_hashReveal + +```solidity +function _hashReveal( + uint256 prevTokenId, + uint256[] calldata amounts, + string[] calldata metadataHashes, + bytes32[] calldata revealHashes + ) internal view returns (bytes32 digest) +``` + +Hashes the data for a reveal creating digest for EIP712 signature. + +Parameters: + +- `prevTokenId` - The ID of the token that hides the assets to be revealed. +- `amounts` - The amounts of each new token to mint. +- `metadataHashes` - The hashes of the metadata for each new token. +- `revealHashes` - The reveal hashes used for revealing this particular `prevTokenId`. + +### \_hashBatchReveal + +```solidity +function _hashBatchReveal( + uint256[] calldata prevTokenIds, + uint256[][] calldata amounts, + string[][] calldata metadataHashes, + bytes32[][] calldata revealHashes + ) internal view returns (bytes32 digest) +``` + +Hashes the data for a batch reveal creating digest for EIP712 signature. + +Parameters: + +- `prevTokenIds` - The IDs of the tokens that hide the assets to be revealed. +- `amounts` - The amounts of each new token to mint for each `prevTokenId`. +- `metadataHashes` - The hashes of the metadata for each new token for each `prevTokenId`. +- `revealHashes` - The reveal hashes used for revealing each particular `prevTokenId`. + +### \_encodeHashes + +```solidity +function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) +``` + +Encodes the metadata hashes into a single bytes32 value. + +Parameters: + +- `metadataHashes` - The hashes of the metadata for each new token. + +### \_encodeBatchHashes + +```solidity +function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) +``` + +Encodes the metadata hashes into a single bytes32 value. + +Parameters: + +- `metadataHashes` - The hashes of the metadata for each new token for each `prevTokenId`. + +### \_encodeBatchRevealHashes + +```solidity +function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) +``` + +Encodes the reveal hashes into a single bytes32 value. + +Parameters: + +- `revealHashes` - The reveal hashes used for revealing each particular `prevTokenId`. + +### \_encodeBatchAmounts + +```solidity +function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) +``` + +Encodes the amounts into a single bytes32 value. + +Parameters: + +- `amounts` - The amounts of each new token to mint for each `prevTokenId`. + +### getRevealedTokenIds + +```solidity +function getRevealedTokenIds( + string[] calldata metadataHashes, + uint256 prevTokenId + ) internal returns (uint256[] memory) +``` + +Depending on whether the asset has been previously revealed to a given metadata hash, this function will either generate a new token ID or return the existing one. + +Parameters: + +- `metadataHashes` - The hashes of the metadata for each new token. +- `prevTokenId` - The ID of the token that hides the assets to be revealed. diff --git a/packages/asset/docs/Catalyst.md b/packages/asset/docs/Catalyst.md new file mode 100644 index 0000000000..31b373f1df --- /dev/null +++ b/packages/asset/docs/Catalyst.md @@ -0,0 +1,14 @@ +# Catalyst Contract + +Main contract for the Catalysts. + +This contract will launch with 6 initial catalyst tiers + +- Common +- Uncommon +- Rare +- Epic +- Legendary +- Mythic + +The tier 0 is reserved for TSB exclusive assets but those should not have any supply minted. diff --git a/packages/asset/hardhat.config.ts b/packages/asset/hardhat.config.ts new file mode 100644 index 0000000000..da6ebeb9df --- /dev/null +++ b/packages/asset/hardhat.config.ts @@ -0,0 +1,24 @@ +import {HardhatUserConfig} from 'hardhat/config'; +import '@nomicfoundation/hardhat-chai-matchers'; +import 'solidity-coverage'; +import '@openzeppelin/hardhat-upgrades'; + +const config: HardhatUserConfig = { + paths: { + sources: './contracts', + }, + solidity: { + compilers: [ + { + version: '0.8.18', + settings: { + optimizer: { + enabled: true, + runs: 2000, + }, + }, + }, + ], + }, +}; +export default config; diff --git a/packages/asset/package.json b/packages/asset/package.json new file mode 100644 index 0000000000..a8ff45ac10 --- /dev/null +++ b/packages/asset/package.json @@ -0,0 +1,57 @@ +{ + "name": "@sandbox-smart-contracts/asset", + "version": "0.0.1", + "description": "Asset L2 smart contracts", + "scripts": { + "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && solhint --max-warnings 0 \"contracts/**/*.sol\"", + "lint:fix": "eslint --fix \"**/*.{js,ts}\" && solhint --fix \"contracts/**/*.sol\"", + "format": "prettier --check \"**/*.{ts,js,sol}\"", + "format:fix": "prettier --write \"**/*.{ts,js,sol}\"", + "coverage": "hardhat coverage --testfiles 'test/*.ts''test/*.js'", + "node": "hardhat node --no-deploy", + "compile": "hardhat compile", + "test": "hardhat test" + }, + "devDependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@manifoldxyz/libraries-solidity": "^1.0.4", + "@manifoldxyz/royalty-registry-solidity": "^2.0.3", + "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", + "@nomiclabs/hardhat-etherscan": "^3.1.7", + "@openzeppelin/contracts": "^4.9.0", + "@openzeppelin/contracts-upgradeable": "^4.9.0", + "@openzeppelin/hardhat-upgrades": "^1.28.0", + "@sandbox-smart-contracts/dependency-metatx": "*", + "@sandbox-smart-contracts/dependency-operator-filter": "*", + "@sandbox-smart-contracts/dependency-royalty-management": "*", + "@typechain/ethers-v5": "^10.2.1", + "@typechain/hardhat": "^6.1.6", + "@types/chai": "^4.3.5", + "@types/mocha": "^10.0.1", + "@types/node": "^20.1.2", + "@typescript-eslint/eslint-plugin": "^5.59.8", + "@typescript-eslint/parser": "^5.59.8", + "chai": "^4.3.7", + "dotenv": "^16.1.4", + "eslint": "^8.41.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-mocha": "^10.1.0", + "eslint-plugin-prettier": "^4.2.1", + "ethers": "^5.7.2", + "hardhat": "^2.14.1", + "hardhat-gas-reporter": "^1.0.9", + "operator-filter-registry": "^1.4.2", + "prettier": "^2.8.8", + "prettier-plugin-solidity": "1.0.0-beta.11", + "solhint": "^3.4.1", + "solhint-plugin-prettier": "^0.0.5", + "solidity-coverage": "^0.8.2", + "ts-node": "^10.9.1", + "typechain": "^8.1.1", + "typescript": "^5.0.4" + } +} diff --git a/packages/asset/test/Asset.test.ts b/packages/asset/test/Asset.test.ts new file mode 100644 index 0000000000..a4f2458644 --- /dev/null +++ b/packages/asset/test/Asset.test.ts @@ -0,0 +1,2247 @@ +import {expect} from 'chai'; +import {ethers, upgrades} from 'hardhat'; +import {runAssetSetup} from './fixtures/asset/assetFixture'; +import {setupOperatorFilter} from './fixtures/operatorFilterFixture'; +import { + AccessControlInterfaceId, + ERC1155InterfaceId, + ERC1155MetadataURIInterfaceId, + ERC165InterfaceId, + ERC2981InterfaceId, + RoyaltyMultiDistributorInterfaceId, + RoyaltyMultiRecipientsInterfaceId, + RoyaltyUGCInterfaceId, +} from './utils/interfaceIds'; +import {BigNumber} from 'ethers'; +const zeroAddress = '0x0000000000000000000000000000000000000000'; + +describe('Base Asset Contract (/packages/asset/contracts/Asset.sol)', function () { + describe('Access Control', function () { + it('should have MINTER_ROLE defined', async function () { + const {AssetContract} = await runAssetSetup(); + const minterRole = await AssetContract.MINTER_ROLE(); + expect(minterRole).to.be.equal(ethers.utils.id('MINTER_ROLE')); + }); + it('should have BURNER_ROLE defined', async function () { + const {AssetContract} = await runAssetSetup(); + const burnerRole = await AssetContract.BURNER_ROLE(); + expect(burnerRole).to.be.equal(ethers.utils.id('BURNER_ROLE')); + }); + it('should be able to grant roles', async function () { + const {AssetContract, AssetContractAsAdmin, owner} = + await runAssetSetup(); + + await AssetContractAsAdmin.grantRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ); + + expect( + await AssetContract.hasRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ) + ).to.be.true; + }); + it('should be able to revoke roles', async function () { + const {AssetContract, AssetContractAsAdmin, owner} = + await runAssetSetup(); + + await AssetContractAsAdmin.grantRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ); + + expect( + await AssetContract.hasRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ) + ).to.be.true; + + await AssetContractAsAdmin.revokeRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ); + + expect( + await AssetContract.hasRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ) + ).to.be.false; + }); + it('should emit RoleGranted event when granting roles', async function () { + const {AssetContract, AssetContractAsAdmin, owner} = + await runAssetSetup(); + + const tx = await AssetContractAsAdmin.grantRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ); + + await expect(tx).to.emit(AssetContract, 'RoleGranted'); + }); + it('should emit RoleRevoked event when revoking roles', async function () { + const {AssetContract, AssetContractAsAdmin, owner} = + await runAssetSetup(); + + await AssetContractAsAdmin.grantRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ); + + const tx = await AssetContractAsAdmin.revokeRole( + ethers.utils.id('BURNER_ROLE'), + owner.address + ); + + await expect(tx).to.emit(AssetContract, 'RoleRevoked'); + }); + it('should not allow non-DEFAULT_ADMIN to grant roles', async function () { + const {AssetContractAsMinter, minter, defaultAdminRole} = + await runAssetSetup(); + + await expect( + AssetContractAsMinter.grantRole( + ethers.utils.id('BURNER_ROLE'), + minter.address + ) + ).to.be.revertedWith( + `AccessControl: account ${minter.address.toLowerCase()} is missing role ${defaultAdminRole}` + ); + }); + }); + describe('Base URI', function () { + it('Should have correct base URI set in the constructor', async function () { + const {AssetContract, mintOne, baseURI} = await runAssetSetup(); + const {tokenId, metadataHash} = await mintOne(); + const tokenURI = await AssetContract.uri(tokenId); + const extractedBaseURI = tokenURI.split(metadataHash)[0]; + expect(extractedBaseURI).to.be.equal(baseURI); + }); + it('Should allow DEFAULT_ADMIN to change base URI', async function () { + const {AssetContract, AssetContractAsAdmin, mintOne} = + await runAssetSetup(); + await AssetContractAsAdmin.setBaseURI('newBaseURI'); + const {tokenId, metadataHash} = await mintOne(); + const tokenURI = await AssetContract.uri(tokenId); + const extractedBaseURI = tokenURI.split(metadataHash)[0]; + expect(extractedBaseURI).to.be.equal('newBaseURI'); + }); + it('Should not allow non-DEFAULT_ADMIN to change base URI', async function () { + const {AssetContractAsMinter, minter, defaultAdminRole} = + await runAssetSetup(); + await expect( + AssetContractAsMinter.setBaseURI('newBaseURI') + ).to.be.revertedWith( + `AccessControl: account ${minter.address.toLowerCase()} is missing role ${defaultAdminRole}` + ); + }); + }); + describe('Token URI', function () { + it('Should return correct token URI', async function () { + const {AssetContract, mintOne, baseURI, metadataHashes} = + await runAssetSetup(); + const {tokenId} = await mintOne(); + const tokenURI = await AssetContract.uri(tokenId); + expect(tokenURI).to.be.equal(baseURI + metadataHashes[0]); + }); + it('Should allow MODERATOR_ROLE to change token URI', async function () { + const { + AssetContract, + AssetContractAsOwner, + owner, + AssetContractAsAdmin, + mintOne, + metadataHashes, + baseURI, + } = await runAssetSetup(); + const {tokenId} = await mintOne(); + const tokenURI = await AssetContract.uri(tokenId); + expect(tokenURI).to.be.equal(baseURI + metadataHashes[0]); + // grant moderator role to owner + await AssetContractAsAdmin.grantRole( + ethers.utils.id('MODERATOR_ROLE'), + owner.address + ); + await AssetContractAsOwner.setTokenURI(tokenId, metadataHashes[1]); + const newTokenURI = await AssetContract.uri(tokenId); + expect(newTokenURI).to.be.equal(baseURI + metadataHashes[1]); + }); + it('Should not allow unauthorized accounts to change token URI', async function () { + const {AssetContractAsMinter, mintOne, metadataHashes, minter} = + await runAssetSetup(); + const {tokenId} = await mintOne(); + await expect( + AssetContractAsMinter.setTokenURI(tokenId, metadataHashes[1]) + ).to.be.revertedWith( + `AccessControl: account ${minter.address.toLowerCase()} is missing role ${ethers.utils.id( + 'MODERATOR_ROLE' + )}` + ); + }); + }); + describe('Minting', function () { + it('Should allow account with MINTER_ROLE to mint', async function () { + const { + AssetContractAsMinter, + generateRandomTokenId, + minter, + metadataHashes, + } = await runAssetSetup(); + const tokenId = generateRandomTokenId(); + const amount = 1; + await expect( + AssetContractAsMinter.mint( + minter.address, + tokenId, + amount, + metadataHashes[0] + ) + ).to.not.be.reverted; + }); + it('Should not allow account without MINTER_ROLE to mint', async function () { + const { + AssetContractAsAdmin, + generateRandomTokenId, + assetAdmin, + metadataHashes, + minterRole, + } = await runAssetSetup(); + const tokenId = generateRandomTokenId(); + const amount = 1; + await expect( + AssetContractAsAdmin.mint( + assetAdmin.address, + tokenId, + amount, + metadataHashes[0] + ) + ).to.be.revertedWith( + `AccessControl: account ${assetAdmin.address.toLowerCase()} is missing role ${minterRole}` + ); + }); + it('Should mark the metadata hash as used after minting', async function () { + const {AssetContract, mintOne} = await runAssetSetup(); + const {tokenId, metadataHash} = await mintOne(); + const linkedTokenId = await AssetContract.hashUsed(metadataHash); + expect(linkedTokenId).to.be.equal(ethers.utils.hexlify(tokenId)); + }); + describe('Single Mint', function () { + it('Should mint tokens with correct amounts', async function () { + const {AssetContract, mintOne, minter} = await runAssetSetup(); + const amount = 3; + const {tokenId} = await mintOne(undefined, undefined, amount); + const balance = await AssetContract.balanceOf(minter.address, tokenId); + expect(balance).to.be.equal(3); + }); + it('Should mint tokens with correct URI', async function () { + const {AssetContract, mintOne, metadataHashes, baseURI} = + await runAssetSetup(); + const {tokenId} = await mintOne(); + const tokenURI = await AssetContract.uri(tokenId); + expect(tokenURI).to.be.equal(baseURI + metadataHashes[0]); + }); + it('Should mint tokens with correct owner', async function () { + const {AssetContract, mintOne, owner} = await runAssetSetup(); + const amount = 1; + const {tokenId} = await mintOne(owner.address, undefined, amount); + const balance = await AssetContract.balanceOf(owner.address, tokenId); + expect(balance).to.be.equal(amount); + }); + it('should not allow minting with duplicate metadata hash', async function () { + const {mintOne, metadataHashes} = await runAssetSetup(); + await mintOne(undefined, undefined, undefined, metadataHashes[0]); + await expect( + mintOne(undefined, undefined, undefined, metadataHashes[0]) + ).to.be.revertedWith('Asset: Hash already used'); + }); + }); + describe('Batch Mint', function () { + it('Should mint tokens with correct amounts', async function () { + const {AssetContract, mintBatch, minter} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(undefined, undefined, amounts); + const balance = await AssetContract.balanceOfBatch( + new Array(tokenIds.length).fill(minter.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + }); + it('Should mint tokens with correct URIs', async function () { + const {AssetContract, mintBatch, metadataHashes, baseURI} = + await runAssetSetup(); + const hashes = [metadataHashes[2], metadataHashes[3]]; + const {tokenIds} = await mintBatch( + undefined, + undefined, + undefined, + hashes + ); + const tokenURI1 = await AssetContract.uri(tokenIds[0]); + const tokenURI2 = await AssetContract.uri(tokenIds[1]); + expect(tokenURI1).to.be.equal(baseURI + hashes[0]); + expect(tokenURI2).to.be.equal(baseURI + hashes[1]); + }); + it('Should mint tokens with correct owner', async function () { + const {AssetContract, mintBatch, owner} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const balance = await AssetContract.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + }); + it('should not allow minting with duplicate metadata hash in a batch', async function () { + const {mintBatch, metadataHashes} = await runAssetSetup(); + await expect( + mintBatch(undefined, undefined, undefined, [ + metadataHashes[0], + metadataHashes[0], + ]) + ).to.be.revertedWith('Asset: Hash already used'); + }); + it('should not allow minting with already existing metadata hash', async function () { + const {mintOne, mintBatch, metadataHashes} = await runAssetSetup(); + await mintOne(undefined, undefined, undefined, metadataHashes[0]); + await expect( + mintBatch(undefined, undefined, undefined, [ + metadataHashes[0], + metadataHashes[1], + ]) + ).to.be.revertedWith('Asset: Hash already used'); + }); + it("should not allow minting if the length of the ids and amounts don't match", async function () { + const {AssetContractAsMinter, generateRandomTokenId, minter} = + await runAssetSetup(); + const tokenIds = [ + generateRandomTokenId(), + generateRandomTokenId(), + generateRandomTokenId(), + ]; + const amounts = [1, 2]; + const hashes = ['0x1', '0x2', '0x3']; + await expect( + AssetContractAsMinter.mintBatch( + minter.address, + tokenIds, + amounts, + hashes + ) + ).to.be.revertedWith('Asset: 2-Array mismatch'); + }); + it("should not allow minting if the length of the ids and hashes don't match", async function () { + const {AssetContractAsMinter, generateRandomTokenId, minter} = + await runAssetSetup(); + const tokenIds = [generateRandomTokenId(), generateRandomTokenId()]; + const amounts = [1, 2]; + const hashes = ['0x1']; + await expect( + AssetContractAsMinter.mintBatch( + minter.address, + tokenIds, + amounts, + hashes + ) + ).to.be.revertedWith('Asset: 1-Array mismatch'); + }); + }); + describe('Mint Events', function () { + it('Should emit TransferSingle event on single mint', async function () { + const {AssetContract, mintOne} = await runAssetSetup(); + + const {tx} = await mintOne(); + await expect(tx).to.emit(AssetContract, 'TransferSingle'); + }); + it('Should emit TransferSingle event with correct args on single mint', async function () { + const {AssetContract, mintOne, generateRandomTokenId, minter} = + await runAssetSetup(); + const tokenId = generateRandomTokenId(); + const amount = 3; + const recipient = minter.address; + const {tx} = await mintOne(recipient, tokenId, amount); + await expect(tx) + .to.emit(AssetContract, 'TransferSingle') + .withArgs( + minter.address, + ethers.constants.AddressZero, + recipient, + tokenId, + amount + ); + }); + it('Should emit TransferBatch event on batch mint', async function () { + const {AssetContract, mintBatch} = await runAssetSetup(); + const {tx} = await mintBatch(); + await expect(tx).to.emit(AssetContract, 'TransferBatch'); + }); + it('Should emit TransferBatch event with correct args on batch mint', async function () { + const {AssetContract, mintBatch, generateRandomTokenId, minter} = + await runAssetSetup(); + const tokenIds = [generateRandomTokenId(), generateRandomTokenId()]; + const amounts = [7, 2]; + const recipient = minter.address; + const {tx} = await mintBatch(recipient, tokenIds, amounts); + await expect(tx) + .to.emit(AssetContract, 'TransferBatch') + .withArgs( + minter.address, + ethers.constants.AddressZero, + recipient, + [ + ethers.utils.hexlify(tokenIds[0]), + ethers.utils.hexlify(tokenIds[1]), + ], + amounts + ); + }); + }); + }); + describe('Burning', function () { + it('Should allow account with BURNER_ROLE to burn tokens from any account', async function () { + const {AssetContract, mintOne, burnOne, owner} = await runAssetSetup(); + const {tokenId} = await mintOne(owner.address, undefined, 10); + expect(await AssetContract.balanceOf(owner.address, tokenId)).to.be.equal( + 10 + ); + await burnOne(owner.address, tokenId, 5); + const balanceAfterBurn = await AssetContract.balanceOf( + owner.address, + tokenId + ); + expect(balanceAfterBurn).to.be.equal(5); + }); + it('Should not allow account without BURNER_ROLE to burn tokens from any account', async function () { + const { + AssetContract, + AssetContractAsMinter, + mintOne, + owner, + burnerRole, + minter, + } = await runAssetSetup(); + const {tokenId} = await mintOne(owner.address, undefined, 10); + expect(await AssetContract.balanceOf(owner.address, tokenId)).to.be.equal( + 10 + ); + await expect( + AssetContractAsMinter.burnFrom(owner.address, tokenId, 5) + ).to.be.revertedWith( + `AccessControl: account ${minter.address.toLowerCase()} is missing role ${burnerRole}` + ); + }); + it('Should allow account with BURNER_ROLE to burn batch of tokens from any account', async function () { + const {AssetContract, mintBatch, burnBatch, owner} = + await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const balance = await AssetContract.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + await burnBatch(owner.address, tokenIds, [1, 1]); + const balanceAfterBurn = await AssetContract.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balanceAfterBurn).to.be.deep.equal([1, 3]); + }); + it('Should not allow account without BURNER_ROLE to burn batch of tokens from any account', async function () { + const { + AssetContract, + AssetContractAsMinter, + mintBatch, + owner, + burnerRole, + minter, + } = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const balance = await AssetContract.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + await expect( + AssetContractAsMinter.burnBatchFrom(owner.address, tokenIds, [1, 1]) + ).to.be.revertedWith( + `AccessControl: account ${minter.address.toLowerCase()} is missing role ${burnerRole}` + ); + }); + it('should allow users to burn their own tokens - single token', async function () { + const {AssetContractAsOwner, mintOne, owner} = await runAssetSetup(); + const {tokenId} = await mintOne(owner.address, undefined, 10); + expect( + await AssetContractAsOwner.balanceOf(owner.address, tokenId) + ).to.be.equal(10); + await AssetContractAsOwner.burn(owner.address, tokenId, 5); + const balanceAfterBurn = await AssetContractAsOwner.balanceOf( + owner.address, + tokenId + ); + expect(balanceAfterBurn).to.be.equal(5); + }); + it('should allow users to burn their own tokens - batch of tokens', async function () { + const {AssetContractAsOwner, mintBatch, owner} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const balance = await AssetContractAsOwner.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + await AssetContractAsOwner.burnBatch(owner.address, tokenIds, [1, 1]); + const balanceAfterBurn = await AssetContractAsOwner.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balanceAfterBurn).to.be.deep.equal([1, 3]); + }); + describe('Burning Events', function () { + it('should emit TransferSingle event on burnFrom', async function () { + const {AssetContractAsBurner, mintOne, minter} = await runAssetSetup(); + const {tokenId} = await mintOne(); + const tx = await AssetContractAsBurner.burnFrom( + minter.address, + tokenId, + 5 + ); + await expect(tx).to.emit(AssetContractAsBurner, 'TransferSingle'); + }); + it('should emit TransferSingle event with correct args on burnFrom', async function () { + const {AssetContractAsBurner, mintOne, minter, burner} = + await runAssetSetup(); + const {tokenId} = await mintOne(); + const tx = await AssetContractAsBurner.burnFrom( + minter.address, + tokenId, + 5 + ); + await expect(tx) + .to.emit(AssetContractAsBurner, 'TransferSingle') + .withArgs( + burner.address, + minter.address, + ethers.constants.AddressZero, + tokenId, + 5 + ); + }); + it('should emit TransferBatch event on burnBatchFrom', async function () { + const {AssetContractAsBurner, mintBatch, minter} = + await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(minter.address, undefined, amounts); + const tx = await AssetContractAsBurner.burnBatchFrom( + minter.address, + tokenIds, + [1, 1] + ); + await expect(tx).to.emit(AssetContractAsBurner, 'TransferBatch'); + }); + it('should emit TransferBatch event with correct args on burnBatchFrom', async function () { + const {AssetContractAsBurner, mintBatch, minter, burner} = + await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(minter.address, undefined, amounts); + const tx = await AssetContractAsBurner.burnBatchFrom( + minter.address, + tokenIds, + [1, 1] + ); + await expect(tx) + .to.emit(AssetContractAsBurner, 'TransferBatch') + .withArgs( + burner.address, + minter.address, + ethers.constants.AddressZero, + [ + ethers.utils.hexlify(tokenIds[0]), + ethers.utils.hexlify(tokenIds[1]), + ], + [1, 1] + ); + }); + it("should emit TransferSingle event on owner's burn", async function () { + const {AssetContractAsOwner, mintOne, owner} = await runAssetSetup(); + const {tokenId} = await mintOne(owner.address, undefined, 10); + const tx = await AssetContractAsOwner.burn(owner.address, tokenId, 5); + await expect(tx).to.emit(AssetContractAsOwner, 'TransferSingle'); + }); + it("should emit TransferSingle event with correct args on owner's burn", async function () { + const {AssetContractAsOwner, mintOne, owner} = await runAssetSetup(); + const {tokenId} = await mintOne(owner.address, undefined, 10); + const tx = await AssetContractAsOwner.burn(owner.address, tokenId, 5); + await expect(tx) + .to.emit(AssetContractAsOwner, 'TransferSingle') + .withArgs( + owner.address, + owner.address, + ethers.constants.AddressZero, + tokenId, + 5 + ); + }); + it("should emit TransferBatch event on owner's burnBatch", async function () { + const {AssetContractAsOwner, mintBatch, owner} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const tx = await AssetContractAsOwner.burnBatch( + owner.address, + tokenIds, + [1, 1] + ); + await expect(tx).to.emit(AssetContractAsOwner, 'TransferBatch'); + }); + it("should emit TransferBatch event with correct args on owner's burnBatch", async function () { + const {AssetContractAsOwner, mintBatch, owner} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const tx = await AssetContractAsOwner.burnBatch( + owner.address, + tokenIds, + [1, 1] + ); + await expect(tx) + .to.emit(AssetContractAsOwner, 'TransferBatch') + .withArgs( + owner.address, + owner.address, + ethers.constants.AddressZero, + [ + ethers.utils.hexlify(tokenIds[0]), + ethers.utils.hexlify(tokenIds[1]), + ], + [1, 1] + ); + }); + }); + }); + describe('Trusted Forwarder', function () { + it('should allow to read the trusted forwarder', async function () { + const {AssetContract, trustedForwarder} = await runAssetSetup(); + expect(await AssetContract.getTrustedForwarder()).to.be.equal( + trustedForwarder.address + ); + }); + it('should correctly check if an address is a trusted forwarder or not', async function () { + const {AssetContract, trustedForwarder} = await runAssetSetup(); + expect(await AssetContract.isTrustedForwarder(trustedForwarder.address)) + .to.be.true; + expect( + await AssetContract.isTrustedForwarder(ethers.constants.AddressZero) + ).to.be.false; + }); + it('should return correct msgData', async function () { + const {MockAssetContract} = await runAssetSetup(); + // call the function to satisfy the coverage only + await MockAssetContract.msgData(); + }); + it('should allow DEFAULT_ADMIN to set the trusted forwarder ', async function () { + const {AssetContract} = await runAssetSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + await AssetContract.setTrustedForwarder(randomAddress); + expect(await AssetContract.getTrustedForwarder()).to.be.equal( + randomAddress + ); + }); + it("should not allow non-DEFAULT_ADMIN to set the trusted forwarder's address", async function () { + const {AssetContractAsMinter, minter, defaultAdminRole} = + await runAssetSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + await expect( + AssetContractAsMinter.setTrustedForwarder(randomAddress) + ).to.be.revertedWith( + `AccessControl: account ${minter.address.toLowerCase()} is missing role ${defaultAdminRole}` + ); + }); + }); + describe('Transferring', function () { + it('should allow owner to transfer a single token', async function () { + const {AssetContractAsOwner, mintOne, owner} = await runAssetSetup(); + const {tokenId} = await mintOne(owner.address, undefined, 10); + await AssetContractAsOwner.safeTransferFrom( + owner.address, + ethers.Wallet.createRandom().address, + tokenId, + 5, + '0x' + ); + const balanceAfterTransfer = await AssetContractAsOwner.balanceOf( + owner.address, + tokenId + ); + expect(balanceAfterTransfer).to.be.equal(5); + }); + it('should allow owner to transfer a batch of tokens', async function () { + const {AssetContractAsOwner, mintBatch, owner} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const balance = await AssetContractAsOwner.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + await AssetContractAsOwner.safeBatchTransferFrom( + owner.address, + ethers.Wallet.createRandom().address, + tokenIds, + [1, 1], + '0x' + ); + const balanceAfterTransfer = await AssetContractAsOwner.balanceOfBatch( + new Array(tokenIds.length).fill(owner.address), + tokenIds + ); + expect(balanceAfterTransfer).to.be.deep.equal([1, 3]); + }); + it('should allow non-owner to transfer a single token if approved', async function () { + const { + AssetContractAsMinter, + AssetContractAsOwner, + mintOne, + minter, + owner, + } = await runAssetSetup(); + const {tokenId} = await mintOne(minter.address, undefined, 10); + await AssetContractAsMinter.setApprovalForAll(owner.address, true); + await AssetContractAsOwner.safeTransferFrom( + minter.address, + ethers.Wallet.createRandom().address, + tokenId, + 5, + '0x' + ); + const balanceAfterTransfer = await AssetContractAsMinter.balanceOf( + minter.address, + tokenId + ); + expect(balanceAfterTransfer).to.be.equal(5); + }); + it('should allow non-owner to transfer a batch of tokens if approved', async function () { + const { + AssetContractAsMinter, + AssetContractAsOwner, + mintBatch, + minter, + owner, + } = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(minter.address, undefined, amounts); + const balance = await AssetContractAsMinter.balanceOfBatch( + new Array(tokenIds.length).fill(minter.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + await AssetContractAsMinter.setApprovalForAll(owner.address, true); + await AssetContractAsOwner.safeBatchTransferFrom( + minter.address, + ethers.Wallet.createRandom().address, + tokenIds, + [1, 1], + '0x' + ); + const balanceAfterTransfer = await AssetContractAsMinter.balanceOfBatch( + new Array(tokenIds.length).fill(minter.address), + tokenIds + ); + expect(balanceAfterTransfer).to.be.deep.equal([1, 3]); + }); + it('should not allow non-owner to transfer a single token if not approved', async function () { + const {AssetContractAsOwner, mintOne, minter} = await runAssetSetup(); + const {tokenId} = await mintOne(minter.address, undefined, 10); + await expect( + AssetContractAsOwner.safeTransferFrom( + minter.address, + ethers.Wallet.createRandom().address, + tokenId, + 5, + '0x' + ) + ).to.be.revertedWith('Asset: Transfer error'); + }); + it('should not allow non-owner to transfer a batch of tokens if not approved', async function () { + const {AssetContractAsOwner, mintBatch, minter} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(minter.address, undefined, amounts); + const balance = await AssetContractAsOwner.balanceOfBatch( + new Array(tokenIds.length).fill(minter.address), + tokenIds + ); + expect(balance).to.be.deep.equal(amounts); + await expect( + AssetContractAsOwner.safeBatchTransferFrom( + minter.address, + ethers.Wallet.createRandom().address, + tokenIds, + [1, 1], + '0x' + ) + ).to.be.revertedWith('ERC1155: caller is not token owner or approved'); + }); + it('should emit TransferSingle event on single transfer', async function () { + const {AssetContractAsOwner, mintOne, owner} = await runAssetSetup(); + const {tokenId} = await mintOne(owner.address, undefined, 10); + const tx = await AssetContractAsOwner.safeTransferFrom( + owner.address, + ethers.Wallet.createRandom().address, + tokenId, + 5, + '0x' + ); + await expect(tx).to.emit(AssetContractAsOwner, 'TransferSingle'); + }); + it('should emit TransferBatch event on batch transfer', async function () { + const {AssetContractAsOwner, mintBatch, owner} = await runAssetSetup(); + const amounts = [2, 4]; + const {tokenIds} = await mintBatch(owner.address, undefined, amounts); + const tx = await AssetContractAsOwner.safeBatchTransferFrom( + owner.address, + ethers.Wallet.createRandom().address, + tokenIds, + [1, 1], + '0x' + ); + await expect(tx).to.emit(AssetContractAsOwner, 'TransferBatch'); + }); + }); + describe('Approving', function () { + it('should allow owners to approve other accounts to use their tokens', async function () { + const {AssetContractAsOwner, owner} = await runAssetSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + await AssetContractAsOwner.setApprovalForAll(randomAddress, true); + const approved = await AssetContractAsOwner.isApprovedForAll( + owner.address, + randomAddress + ); + expect(approved).to.be.true; + }); + it('should emit ApprovalForAll event approval', async function () { + const {AssetContractAsOwner} = await runAssetSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + const tx = await AssetContractAsOwner.setApprovalForAll( + randomAddress, + true + ); + await expect(tx).to.emit(AssetContractAsOwner, 'ApprovalForAll'); + }); + }); + describe('Interface support', function () { + it('should support ERC165', async function () { + const {AssetContract} = await runAssetSetup(); + expect(await AssetContract.supportsInterface(ERC165InterfaceId)).to.be + .true; + }); + it('should support ERC1155', async function () { + const {AssetContract} = await runAssetSetup(); + expect(await AssetContract.supportsInterface(ERC1155InterfaceId)).to.be + .true; + }); + it('should support ERC1155MetadataURI', async function () { + const {AssetContract} = await runAssetSetup(); + expect( + await AssetContract.supportsInterface(ERC1155MetadataURIInterfaceId) + ).to.be.true; + }); + it('should support AccessControlUpgradeable', async function () { + const {AssetContract} = await runAssetSetup(); + expect(await AssetContract.supportsInterface(AccessControlInterfaceId)).to + .be.true; + }); + it('should support IRoyaltyUGC', async function () { + const {AssetContract} = await runAssetSetup(); + expect(await AssetContract.supportsInterface(RoyaltyUGCInterfaceId)).to.be + .true; + }); + it('should support IRoyaltyMultiDistributor', async function () { + const {AssetContract} = await runAssetSetup(); + expect( + await AssetContract.supportsInterface( + RoyaltyMultiDistributorInterfaceId + ) + ).to.be.true; + }); + it('should support IRoyaltyMultiRecipients', async function () { + const {AssetContract} = await runAssetSetup(); + expect( + await AssetContract.supportsInterface(RoyaltyMultiRecipientsInterfaceId) + ).to.be.true; + }); + it('should support IERC2981', async function () { + const {AssetContract} = await runAssetSetup(); + expect(await AssetContract.supportsInterface(ERC2981InterfaceId)).to.be + .true; + }); + }); + describe('Token util', function () { + it('should return correct creator from asset for a token', async function () { + const {AssetContractAsMinter, generateAssetId, owner} = + await runAssetSetup(); + + const tier = 4; + const revealNonce = 1; + const creatorNonce = 1; + const bridgeMinted = false; + + const tokenId = generateAssetId( + owner.address, + tier, + creatorNonce, + revealNonce, + bridgeMinted + ); + + await AssetContractAsMinter.mint(owner.address, tokenId, 1, '0x'); + + expect(await AssetContractAsMinter.getCreatorAddress(tokenId)).to.equal( + owner.address + ); + }); + + it('should return correct bridged information from asset for a token', async function () { + const {AssetContractAsMinter, generateAssetId, owner} = + await runAssetSetup(); + + const tier = 4; + const revealNonce = 1; + const creatorNonce = 1; + const bridgeMinted = false; + + const tokenId = generateAssetId( + owner.address, + tier, + creatorNonce, + revealNonce, + bridgeMinted + ); + await AssetContractAsMinter.mint(owner.address, tokenId, 1, '0x'); + + expect(await AssetContractAsMinter.isBridged(tokenId)).to.equal( + bridgeMinted + ); + }); + it('should return correct tier from asset for a token', async function () { + const {AssetContractAsMinter, generateAssetId, owner} = + await runAssetSetup(); + + const tier = 4; + const revealNonce = 1; + const creatorNonce = 1; + const bridgeMinted = false; + + const tokenId = generateAssetId( + owner.address, + tier, + creatorNonce, + revealNonce, + bridgeMinted + ); + + await AssetContractAsMinter.mint(owner.address, tokenId, 1, '0x'); + + expect(await AssetContractAsMinter.getTier(tokenId)).to.equal(tier); + }); + it('should return correct revealed information from asset for a token', async function () { + const {AssetContractAsMinter, generateAssetId, owner} = + await runAssetSetup(); + + const tier = 4; + const revealNonce = 1; + const creatorNonce = 1; + const bridgeMinted = false; + + const tokenId = generateAssetId( + owner.address, + tier, + creatorNonce, + revealNonce, + bridgeMinted + ); + + await AssetContractAsMinter.mint(owner.address, tokenId, 1, '0x'); + + expect(await AssetContractAsMinter.isRevealed(tokenId)).to.equal(true); + expect(await AssetContractAsMinter.getRevealNonce(tokenId)).to.equal( + revealNonce + ); + }); + it('should return correct creator nonce from asset for a token', async function () { + const {AssetContractAsMinter, generateAssetId, owner} = + await runAssetSetup(); + + const tier = 4; + const revealNonce = 1; + const creatorNonce = 1; + const bridgeMinted = false; + + const tokenId = generateAssetId( + owner.address, + tier, + creatorNonce, + revealNonce, + bridgeMinted + ); + + await AssetContractAsMinter.mint(owner.address, tokenId, 1, '0x'); + expect(await AssetContractAsMinter.getCreatorNonce(tokenId)).to.equal( + creatorNonce + ); + }); + }); + describe('OperatorFilterer', function () { + describe('common subscription setup', function () { + it('should be registered', async function () { + const {operatorFilterRegistry, Asset} = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isRegistered(Asset.address) + ).to.be.equal(true); + }); + it('should set registry and subscribe to common subscription', async function () { + const { + operatorFilterRegistry, + assetAdmin, + TrustedForwarder, + filterOperatorSubscription, + RoyaltyManagerContract, + } = await setupOperatorFilter(); + const AssetFactory = await ethers.getContractFactory('Asset'); + const Asset = await upgrades.deployProxy( + AssetFactory, + [ + TrustedForwarder.address, + assetAdmin.address, + 'ipfs://', + filterOperatorSubscription.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await Asset.connect(assetAdmin).setOperatorRegistry( + operatorFilterRegistry.address + ); + expect(await Asset.getOperatorFilterRegistry()).to.be.equals( + operatorFilterRegistry.address + ); + + await Asset.connect(assetAdmin).registerAndSubscribe( + filterOperatorSubscription.address, + true + ); + + expect( + await operatorFilterRegistry.isRegistered(Asset.address) + ).to.be.equals(true); + + expect( + await operatorFilterRegistry.subscriptionOf(Asset.address) + ).to.be.equals(filterOperatorSubscription.address); + }); + + it('should revert when registry is set zero and subscription is set zero', async function () { + const { + assetAdmin, + TrustedForwarder, + filterOperatorSubscription, + RoyaltyManagerContract, + } = await setupOperatorFilter(); + const AssetFactory = await ethers.getContractFactory('Asset'); + const Asset = await upgrades.deployProxy( + AssetFactory, + [ + TrustedForwarder.address, + assetAdmin.address, + 'ipfs://', + filterOperatorSubscription.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await expect( + Asset.connect(assetAdmin).setOperatorRegistry(zeroAddress) + ).to.be.revertedWith('Asset: Zero address'); + + await expect( + Asset.connect(assetAdmin).registerAndSubscribe(zeroAddress, true) + ).to.be.revertedWith('Asset: Zero address'); + }); + + it('should revert when registry is set and subscription is set by non-admin', async function () { + const { + assetAdmin, + TrustedForwarder, + filterOperatorSubscription, + RoyaltyManagerContract, + operatorFilterRegistry, + defaultAdminRole, + user1, + } = await setupOperatorFilter(); + const AssetFactory = await ethers.getContractFactory('Asset'); + const Asset = await upgrades.deployProxy( + AssetFactory, + [ + TrustedForwarder.address, + assetAdmin.address, + 'ipfs://', + filterOperatorSubscription.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await expect( + Asset.connect(user1).setOperatorRegistry( + operatorFilterRegistry.address + ) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${defaultAdminRole}` + ); + + await expect( + Asset.connect(user1).registerAndSubscribe( + filterOperatorSubscription.address, + true + ) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${defaultAdminRole}` + ); + }); + it('should not revert when registry is set and subscription is set by admin through trusted forwarder', async function () { + const { + assetAdmin, + TrustedForwarder, + filterOperatorSubscription, + RoyaltyManagerContract, + operatorFilterRegistry, + defaultAdminRole, + user1, + } = await setupOperatorFilter(); + const AssetFactory = await ethers.getContractFactory('Asset'); + const Asset = await upgrades.deployProxy( + AssetFactory, + [ + TrustedForwarder.address, + assetAdmin.address, + 'ipfs://', + filterOperatorSubscription.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await expect( + Asset.connect(user1).setOperatorRegistry( + operatorFilterRegistry.address + ) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${defaultAdminRole}` + ); + + await expect( + Asset.connect(user1).registerAndSubscribe( + filterOperatorSubscription.address, + true + ) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${defaultAdminRole}` + ); + }); + + it('should be subscribed to common subscription', async function () { + const {operatorFilterRegistry, Asset, filterOperatorSubscription} = + await setupOperatorFilter(); + expect( + await operatorFilterRegistry.subscriptionOf(Asset.address) + ).to.be.equal(filterOperatorSubscription.address); + }); + + it('default subscription should blacklist Mock Market places 1, 2 and not 3, 4', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + DEFAULT_SUBSCRIPTION, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('common subscription should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + filterOperatorSubscription, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('Asset should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + Asset, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it("removing market places from common subscription's blacklist should reflect on asset's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + Asset, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash, + false + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + }); + + it("adding market places to common subscription's blacklist should reflect on asset's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace3, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + Asset, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash, + true + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Asset.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Asset.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + }); + }); + + describe('asset transfer and approval ', function () { + it('should be able to safe transfer asset if from is the owner of token', async function () { + const {Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Asset.safeTransferFrom( + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('should be able to safe batch transfer asset if from is the owner of token', async function () { + const {Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + await Asset.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Asset.safeBatchTransferFrom( + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Asset.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + + it('should be able to safe transfer asset if from is the owner of asset and to is a blacklisted marketplace', async function () { + const {mockMarketPlace1, Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Asset.safeTransferFrom( + users[0].address, + mockMarketPlace1.address, + 1, + 1, + '0x' + ); + + expect(await Asset.balanceOf(mockMarketPlace1.address, 1)).to.be.equal( + 1 + ); + }); + + it('should be able to safe batch transfer assets if from is the owner of assets and to is a blacklisted marketplace', async function () { + const {mockMarketPlace1, Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + await Asset.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Asset.safeBatchTransferFrom( + users[0].address, + mockMarketPlace1.address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Asset.balanceOf(mockMarketPlace1.address, 1)).to.be.equal( + 1 + ); + expect(await Asset.balanceOf(mockMarketPlace1.address, 2)).to.be.equal( + 1 + ); + }); + + it('it should not setApprovalForAll blacklisted market places', async function () { + const {mockMarketPlace1, users} = await setupOperatorFilter(); + + await expect( + users[0].Asset.setApprovalForAll(mockMarketPlace1.address, true) + ).to.be.reverted; + }); + + it('it should setApprovalForAll non blacklisted market places', async function () { + const {mockMarketPlace3, Asset, users} = await setupOperatorFilter(); + await users[0].Asset.setApprovalForAll(mockMarketPlace3.address, true); + expect( + await Asset.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + }); + + it('it should not be able to setApprovalForAll non blacklisted market places after they are blacklisted ', async function () { + const { + mockMarketPlace3, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + Asset, + users, + } = await setupOperatorFilter(); + await users[0].Asset.setApprovalForAll(mockMarketPlace3.address, true); + + expect( + await Asset.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + users[1].Asset.setApprovalForAll(mockMarketPlace3.address, true) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to setApprovalForAll non blacklisted market places after there codeHashes are blacklisted ', async function () { + const { + mockMarketPlace3, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + Asset, + users, + } = await setupOperatorFilter(); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace3.address + ); + + await users[0].Asset.setApprovalForAll(mockMarketPlace3.address, true); + + expect( + await Asset.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + users[1].Asset.setApprovalForAll(mockMarketPlace3.address, true) + ).to.be.revertedWith; + }); + + it('it should not be able to setApprovalForAll trusted forwarder if black listed', async function () { + const { + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + users, + TrustedForwarder, + } = await setupOperatorFilter(); + + const TrustedForwarderCodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + TrustedForwarder.address + ); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + TrustedForwarderCodeHash, + true + ); + + await expect( + users[1].Asset.setApprovalForAll(TrustedForwarder.address, true) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to setApprovalForAll blacklisted market places after they are removed from the blacklist ', async function () { + const { + mockMarketPlace1, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + Asset, + users, + } = await setupOperatorFilter(); + + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace1.address + ); + + await expect( + users[0].Asset.setApprovalForAll(mockMarketPlace1.address, true) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + + await users[0].Asset.setApprovalForAll(mockMarketPlace1.address, true); + + expect( + await Asset.isApprovedForAll( + users[0].address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + }); + + it('it should not be able to transfer through blacklisted market places', async function () { + const {mockMarketPlace1, Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + await expect( + mockMarketPlace1.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to transfer through market places after they are blacklisted', async function () { + const { + mockMarketPlace3, + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + + await mockMarketPlace3.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + mockMarketPlace3.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to transfer through trusted forwarder after it is blacklisted', async function () { + const { + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + TrustedForwarder, + } = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 2); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + TrustedForwarder.address, + true + ); + + const data = await Asset.connect( + users[0].Asset.signer + ).populateTransaction[ + 'safeTransferFrom(address,address,uint256,uint256,bytes)' + ](users[0].address, users[1].address, 1, 1, '0x'); + + await TrustedForwarder.execute({...data, value: BigNumber.from(0)}); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to transfer through trusted forwarder after if sender is blacklisted', async function () { + const {Asset, users, TrustedForwarder, mockMarketPlace1} = + await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + const data = await Asset.connect( + ethers.provider.getSigner(mockMarketPlace1.address) + ).populateTransaction[ + 'safeTransferFrom(address,address,uint256,uint256,bytes)' + ](users[0].address, users[1].address, 1, 1, '0x'); + + await expect( + TrustedForwarder.execute({...data, value: BigNumber.from(0)}) + ).to.be.revertedWith('Call execution failed'); + }); + + it('it should be able to transfer through non blacklisted market places', async function () { + const {mockMarketPlace3, Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to transfer through non blacklisted market places after their codeHash is blacklisted', async function () { + const { + mockMarketPlace3, + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace3.address + ); + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + mockMarketPlace3.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to transfer through blacklisted market places after they are removed from blacklist', async function () { + const { + mockMarketPlace1, + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace1.address + ); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + await expect( + mockMarketPlace1.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + await mockMarketPlace1.transferTokenForERC1155( + Asset.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to batch transfer through blacklisted market places', async function () { + const {mockMarketPlace1, Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + await Asset.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + await expect( + mockMarketPlace1.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to batch transfer through market places after they are blacklisted', async function () { + const { + mockMarketPlace3, + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 2); + await Asset.mintWithoutMinterRole(users[0].address, 2, 2); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + + await mockMarketPlace3.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + + expect(await Asset.balanceOf(users[1].address, 2)).to.be.equal(1); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + mockMarketPlace3.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to batch transfer through non blacklisted market places', async function () { + const {mockMarketPlace3, Asset, users} = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + await Asset.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Asset.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + + it('it should not be able to batch transfer through non blacklisted market places after their codeHash is blacklisted', async function () { + const { + mockMarketPlace3, + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await Asset.mintWithoutMinterRole(users[0].address, 1, 2); + await Asset.mintWithoutMinterRole(users[0].address, 2, 2); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Asset.balanceOf(users[1].address, 2)).to.be.equal(1); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace3.address + ); + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + mockMarketPlace3.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to batch transfer through blacklisted market places after they are removed from blacklist', async function () { + const { + mockMarketPlace1, + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace1.address + ); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + await Asset.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + await expect( + mockMarketPlace1.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + await mockMarketPlace1.batchTransferTokenERC1155( + Asset.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Asset.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + it('should be able to batch transfer through trusted forwarder if it is black listed', async function () { + const { + Asset, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + TrustedForwarder, + } = await setupOperatorFilter(); + const TrustedForwarderCodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + TrustedForwarder.address + ); + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + await Asset.mintWithoutMinterRole(users[0].address, 2, 1); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + TrustedForwarderCodeHash, + true + ); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + TrustedForwarder.address, + true + ); + const data = await Asset.connect( + users[0].Asset.signer + ).populateTransaction[ + 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)' + ](users[0].address, users[1].address, [1, 2], [1, 1], '0x'); + + await TrustedForwarder.execute({...data, value: BigNumber.from(0)}); + expect(await Asset.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Asset.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + it('should not be able to batch transfer through trusted forwarder if the sender is black listed', async function () { + const {Asset, users, TrustedForwarder, mockMarketPlace1} = + await setupOperatorFilter(); + + await Asset.mintWithoutMinterRole(users[0].address, 1, 1); + await Asset.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Asset.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + const data = await Asset.connect( + ethers.provider.getSigner(mockMarketPlace1.address) + ).populateTransaction[ + 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)' + ](users[0].address, users[1].address, [1, 2], [1, 1], '0x'); + + await expect( + TrustedForwarder.execute({...data, value: BigNumber.from(0)}) + ).to.be.revertedWith('Call execution failed'); + }); + }); + }); +}); diff --git a/packages/asset/test/AssetCreate.test.ts b/packages/asset/test/AssetCreate.test.ts new file mode 100644 index 0000000000..da2c189b98 --- /dev/null +++ b/packages/asset/test/AssetCreate.test.ts @@ -0,0 +1,1364 @@ +import {expect} from 'chai'; +import {BigNumber, Event, ethers} from 'ethers'; +import {runCreateTestSetup} from './fixtures/asset/assetCreateFixtures'; + +describe('AssetCreate (/packages/asset/contracts/AssetCreate.sol)', function () { + describe('General', function () { + it('should deploy successfully', async function () { + const {AssetCreateContract} = await runCreateTestSetup(); + + expect(AssetCreateContract.address).to.be.properAddress; + }); + it('should have auth validators contract address set correctly', async function () { + const {AssetCreateContract, AuthValidatorContract} = + await runCreateTestSetup(); + expect(await AssetCreateContract.getAuthValidator()).to.equal( + AuthValidatorContract.address + ); + }); + it('should have catalyst contract address set correctly', async function () { + const {AssetCreateContract, CatalystContract} = + await runCreateTestSetup(); + expect(await AssetCreateContract.getCatalystContract()).to.equal( + CatalystContract.address + ); + }); + it('should have asset contract address set correctly', async function () { + const {AssetCreateContract, AssetContract} = await runCreateTestSetup(); + expect(await AssetCreateContract.getAssetContract()).to.equal( + AssetContract.address + ); + }); + }); + describe('Trusted Forwarder', function () { + it('should allow to read the trusted forwarder', async function () { + const {AssetCreateContract, trustedForwarder} = + await runCreateTestSetup(); + expect(await AssetCreateContract.getTrustedForwarder()).to.be.equal( + trustedForwarder.address + ); + }); + it('should correctly check if an address is a trusted forwarder or not', async function () { + const {AssetCreateContract, trustedForwarder} = + await runCreateTestSetup(); + expect( + await AssetCreateContract.isTrustedForwarder(trustedForwarder.address) + ).to.be.true; + expect( + await AssetCreateContract.isTrustedForwarder( + ethers.constants.AddressZero + ) + ).to.be.false; + }); + it('should allow DEFAULT_ADMIN to set the trusted forwarder ', async function () { + const {AssetCreateContractAsAdmin} = await runCreateTestSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + await AssetCreateContractAsAdmin.setTrustedForwarder(randomAddress); + expect( + await AssetCreateContractAsAdmin.getTrustedForwarder() + ).to.be.equal(randomAddress); + }); + it('should not allow non DEFAULT_ADMIN to set the trusted forwarder ', async function () { + const {AssetCreateContractAsUser, user, AdminRole} = + await runCreateTestSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + await expect( + AssetCreateContractAsUser.setTrustedForwarder(randomAddress) + ).to.be.revertedWith( + `AccessControl: account ${user.address.toLowerCase()} is missing role ${AdminRole}` + ); + }); + it('should return correct msgData', async function () { + const {MockAssetCreateContract} = await runCreateTestSetup(); + // call the function to satisfy the coverage only, but we don't need to check the result + await MockAssetCreateContract.msgData(); + }); + }); + describe('Pausable', function () { + it('should allow pauser to pause the contract', async function () { + const {AssetCreateContract, pause} = await runCreateTestSetup(); + await pause(); + expect(await AssetCreateContract.paused()).to.be.true; + }); + it('should not allow non pauser to pause the contract', async function () { + const {AssetCreateContractAsUser, user, PauserRole} = + await runCreateTestSetup(); + await expect(AssetCreateContractAsUser.pause()).to.be.revertedWith( + `AccessControl: account ${user.address.toLowerCase()} is missing role ${PauserRole}` + ); + }); + it('should allow pauser to unpause the contract', async function () { + const {AssetCreateContract, pause, unpause} = await runCreateTestSetup(); + await pause(); + expect(await AssetCreateContract.paused()).to.be.true; + await unpause(); + expect(await AssetCreateContract.paused()).to.be.false; + }); + it('should not allow non pauser to unpause the contract', async function () { + const {AssetCreateContractAsUser, user, PauserRole} = + await runCreateTestSetup(); + await expect(AssetCreateContractAsUser.unpause()).to.be.revertedWith( + `AccessControl: account ${user.address.toLowerCase()} is missing role ${PauserRole}` + ); + }); + it('should not allow createAsset to be called when paused', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + pause, + } = await runCreateTestSetup(); + await mintCatalyst(4, 1); + const signature = await generateSingleMintSignature( + user.address, + 4, + 1, + true, + metadataHashes[0] + ); + await pause(); + await expect( + mintSingleAsset(signature, 4, 1, true, metadataHashes[0]) + ).to.be.revertedWith('Pausable: paused'); + }); + it('should not allow createMultipleAssets to be called when paused', async function () { + const { + user, + mintCatalyst, + mintMultipleAssets, + generateMultipleMintSignature, + metadataHashes, + pause, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await pause(); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('Pausable: paused'); + }); + it('should not allow createSpecialAsset to be called when paused', async function () { + const { + user, + grantSpecialMinterRole, + mintSpecialAsset, + generateSingleMintSignature, + metadataHashes, + pause, + } = await runCreateTestSetup(); + await grantSpecialMinterRole(user.address); + const signature = await generateSingleMintSignature( + user.address, + 0, + 1, + true, + metadataHashes[0] + ); + await pause(); + await expect( + mintSpecialAsset(signature, 1, metadataHashes[0]) + ).to.be.revertedWith('Pausable: paused'); + }); + it('should allow createAsset to be called when unpaused', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + unpause, + pause, + } = await runCreateTestSetup(); + await pause(); + await mintCatalyst(4, 1); + const signature = await generateSingleMintSignature( + user.address, + 4, + 1, + true, + metadataHashes[0] + ); + await unpause(); + await expect(mintSingleAsset(signature, 4, 1, true, metadataHashes[0])).to + .not.be.reverted; + }); + it('should allow createMultipleAssets to be called when unpaused', async function () { + const { + user, + mintCatalyst, + mintMultipleAssets, + generateMultipleMintSignature, + metadataHashes, + unpause, + pause, + } = await runCreateTestSetup(); + await pause(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await unpause(); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.not.be.reverted; + }); + it('should allow createSpecialAsset to be called when unpaused', async function () { + const { + user, + grantSpecialMinterRole, + mintSpecialAsset, + generateSingleMintSignature, + metadataHashes, + unpause, + pause, + } = await runCreateTestSetup(); + await pause(); + await grantSpecialMinterRole(user.address); + const signature = await generateSingleMintSignature( + user.address, + 0, + 1, + true, + metadataHashes[0] + ); + await unpause(); + await expect(mintSpecialAsset(signature, 1, metadataHashes[0])).to.not.be + .reverted; + }); + }); + describe('Single asset mint', function () { + describe('Success', function () { + it('should mint a single asset successfully if all conditions are met', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 1); + const signature = await generateSingleMintSignature( + user.address, + 4, + 1, + true, + metadataHashes[0] + ); + + await expect(mintSingleAsset(signature, 4, 1, true, metadataHashes[0])) + .to.not.be.reverted; + }); + it('should increment the creator nonce correctly', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + getCreatorNonce, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 1); + const signature = await generateSingleMintSignature( + user.address, + 4, + 1, + true, + metadataHashes[0] + ); + + await expect(mintSingleAsset(signature, 4, 1, true, metadataHashes[0])) + .to.not.be.reverted; + + expect(await getCreatorNonce(user.address)).to.equal(BigNumber.from(1)); + }); + it('should mint the correct amount of assets', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + AssetContract, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 5); + const signature = await generateSingleMintSignature( + user.address, + 4, + 5, + true, + metadataHashes[0] + ); + + const result = await mintSingleAsset( + signature, + 4, + 5, + true, + metadataHashes[0] + ); + + const tokenId = result.events.filter( + (e: Event) => e.event == 'AssetMinted' + )[0].args.tokenId; + + expect(await AssetContract.balanceOf(user.address, tokenId)).to.equal( + BigNumber.from(5) + ); + }); + it('should mint the correct tier of assets', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 5); + const signature = await generateSingleMintSignature( + user.address, + 4, + 5, + true, + metadataHashes[0] + ); + const result = await mintSingleAsset( + signature, + 4, + 5, + true, + metadataHashes[0] + ); + + // get tokenId from the event + const tier = result.events.filter( + (e: Event) => e.event == 'AssetMinted' + )[0].args.tier; + expect(tier).to.equal(4); + }); + it('should mint an asset with correct metadataHash', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + AssetContract, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 5); + const signature = await generateSingleMintSignature( + user.address, + 4, + 5, + true, + metadataHashes[0] + ); + const result = await mintSingleAsset( + signature, + 4, + 5, + true, + metadataHashes[0] + ); + + // get tokenId from the event + const tokenId = result.events.filter( + (e: Event) => e.event == 'AssetMinted' + )[0].args.tokenId; + expect(await AssetContract.hashUsed(metadataHashes[0])).to.equal( + tokenId + ); + }); + }); + describe('Revert', function () { + it('should revert if the signature is invalid', async function () { + const {mintCatalyst, mintSingleAsset, metadataHashes} = + await runCreateTestSetup(); + await mintCatalyst(4, 1); + const signature = + '0x45956f9a4b3f24fcc1a7c1a64f5fe7d21c00dd224a44f868ad8a67fd7b7cf6601e3a69a6a78a6a74377dddd1fa8c0c0f64b766d4a75842c1653b2a1a76c3a0ce1c'; + + await expect( + mintSingleAsset(signature, 4, 1, true, metadataHashes[0]) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if tier mismatches signed tier', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(5, 1); + const signedTier = 4; + const txSuppliedTier = 5; + const signature = await generateSingleMintSignature( + user.address, + signedTier, + 1, + true, + metadataHashes[0] + ); + + await expect( + mintSingleAsset(signature, txSuppliedTier, 1, true, metadataHashes[0]) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if amount mismatches signed amount', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 2); + const signedAmount = 1; + const txSuppliedAmount = 2; + const signature = await generateSingleMintSignature( + user.address, + 4, + signedAmount, + true, + metadataHashes[0] + ); + + await expect( + mintSingleAsset( + signature, + 4, + txSuppliedAmount, + true, + metadataHashes[0] + ) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if sender is not the creator for which the signature was generated', async function () { + const { + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + otherWallet, + } = await runCreateTestSetup(); + await mintCatalyst(4, 1); + const signature = await generateSingleMintSignature( + otherWallet.address, + 4, + 1, + true, + metadataHashes[0] + ); + + await expect( + mintSingleAsset(signature, 4, 1, true, metadataHashes[0]) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if metadataHash mismatches signed metadataHash', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 2); + const signature = await generateSingleMintSignature( + user.address, + 4, + 1, + true, + metadataHashes[0] + ); + + await expect( + mintSingleAsset(signature, 4, 1, true, '0x1234') + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if the signature has been used before', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 2); + const signature = await generateSingleMintSignature( + user.address, + 4, + 1, + true, + metadataHashes[0] + ); + + // expect mint tx not to revert + await expect(mintSingleAsset(signature, 4, 1, true, metadataHashes[0])) + .to.not.be.reverted; + + await expect( + mintSingleAsset(signature, 4, 1, true, metadataHashes[0]) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it("should revert if user doesn't have enough catalysts", async function () { + const { + user, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + const signature = await generateSingleMintSignature( + user.address, + 4, + 1, + true, + metadataHashes[0] + ); + + await expect( + mintSingleAsset(signature, 4, 1, true, metadataHashes[0]) + ).to.be.revertedWith('ERC1155: burn amount exceeds totalSupply'); + }); + it('should NOT allow minting with the same metadata twice', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 4); + const signature1 = await generateSingleMintSignature( + user.address, + 4, + 2, + true, + metadataHashes[0] + ); + await expect(mintSingleAsset(signature1, 4, 2, true, metadataHashes[0])) + .to.not.be.reverted; + const signature2 = await generateSingleMintSignature( + user.address, + 4, + 2, + true, + metadataHashes[0] + ); + await expect( + mintSingleAsset(signature2, 4, 2, true, metadataHashes[0]) + ).to.be.revertedWith('Asset: Hash already used'); + }); + it('should NOT mint same token ids', async function () { + const { + user, + mintCatalyst, + mintSingleAsset, + generateSingleMintSignature, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 4); + const signature1 = await generateSingleMintSignature( + user.address, + 4, + 2, + true, + metadataHashes[0] + ); + const result1 = await mintSingleAsset( + signature1, + 4, + 2, + true, + metadataHashes[0] + ); + const signature2 = await generateSingleMintSignature( + user.address, + 4, + 2, + true, + metadataHashes[1] + ); + const result2 = await mintSingleAsset( + signature2, + 4, + 2, + true, + metadataHashes[1] + ); + + const tokenId1 = result1.events.filter( + (e: Event) => e.event == 'AssetMinted' + )[0].args.tokenId; + + const tokenId2 = result2.events.filter( + (e: Event) => e.event == 'AssetMinted' + )[0].args.tokenId; + + expect(tokenId1).to.not.equal(tokenId2); + }); + }); + describe('Event', function () { + it('should emit an AssetMinted event', async function () { + const { + user, + mintCatalyst, + generateSingleMintSignature, + AssetCreateContract, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 5); + const signature = await generateSingleMintSignature( + user.address, + 4, + 5, + true, + metadataHashes[0] + ); + + await expect( + AssetCreateContract.createAsset( + signature, + 4, + 5, + true, + metadataHashes[0], + user.address + ) + ).to.emit(AssetCreateContract, 'AssetMinted'); + }); + it('should emit AssetMinted event with the correct data', async function () { + const { + user, + mintCatalyst, + generateSingleMintSignature, + mintSingleAsset, + metadataHashes, + } = await runCreateTestSetup(); + await mintCatalyst(4, 5); + const signature = await generateSingleMintSignature( + user.address, + 4, + 5, + true, + metadataHashes[0] + ); + + const result = await mintSingleAsset( + signature, + 4, + 5, + true, + metadataHashes[0] + ); + + const eventData = result.events.filter( + (e: Event) => e.event == 'AssetMinted' + )[0].args; + + // creator should be user + expect(eventData.creator).to.equal(user.address); + // tier should be 4 + expect(eventData.tier).to.equal(4); + // amount should be 5 + expect(eventData.amount).to.equal(5); + // metadataHash should be metadataHashes[0] + expect(eventData.metadataHash).to.equal(metadataHashes[0]); + // revealed should be true + expect(eventData.revealed).to.be.true; + }); + it('should emit catalyst burn event', async function () { + const { + user, + mintCatalyst, + generateSingleMintSignature, + metadataHashes, + AssetCreateContractAsUser, + CatalystContract, + } = await runCreateTestSetup(); + await mintCatalyst(4, 5); + const signature = await generateSingleMintSignature( + user.address, + 4, + 5, + true, + metadataHashes[0] + ); + await expect( + AssetCreateContractAsUser.createAsset( + signature, + 4, + 5, + true, + metadataHashes[0], + user.address + ) + ).to.emit(CatalystContract, 'TransferSingle'); + }); + }); + }); + describe('Multiple assets mint', function () { + describe('Success', function () { + it('should correctly mint multiple assets if all conditions are met', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.not.be.reverted; + }); + it('should mint correct amounts of assets', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + AssetContract, + AssetCreateContract, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 3); + await mintCatalyst(4, 5); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + await mintMultipleAssets( + signature, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + const events = await AssetCreateContract.queryFilter( + 'AssetBatchMinted' + ); + const event = events[0]; + const args = event.args; + expect(args).to.not.be.undefined; + let tokenIds; + if (args != undefined) { + tokenIds = args[1]; + } + + expect( + await AssetContract.balanceOf(user.address, tokenIds[0]) + ).to.equal(3); + expect( + await AssetContract.balanceOf(user.address, tokenIds[1]) + ).to.equal(5); + }); + it('should mint correct tiers of assets', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + AssetCreateContract, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 3); + await mintCatalyst(4, 5); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + await mintMultipleAssets( + signature, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + const events = await AssetCreateContract.queryFilter( + 'AssetBatchMinted' + ); + const event = events[0]; + const args = event.args; + expect(args).to.not.be.undefined; + let tiers; + if (args != undefined) { + tiers = args[2]; + } + + expect(tiers[0]).to.equal(3); + expect(tiers[1]).to.equal(4); + }); + it('should mint assets with correct metadataHashes', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + AssetContract, + AssetCreateContract, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 3); + await mintCatalyst(4, 5); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + await mintMultipleAssets( + signature, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + const events = await AssetCreateContract.queryFilter( + 'AssetBatchMinted' + ); + const event = events[0]; + const args = event.args; + expect(args).to.not.be.undefined; + let tokenIds; + if (args != undefined) { + tokenIds = args[1]; + } + + expect(await AssetContract.hashUsed(metadataHashes[0])).to.equal( + tokenIds[0] + ); + expect(await AssetContract.hashUsed(metadataHashes[1])).to.equal( + tokenIds[1] + ); + }); + }); + describe('Revert', function () { + it('should revert if signature is invalid', async function () { + const {mintMultipleAssets, metadataHashes} = await runCreateTestSetup(); + const signature = + '0x45956f9a4b3f24fcc1a7c1a64f5fe7d21c00dd224a44f868ad8a67fd7b7cf6601e3a69a6a78a6a74377dddd1fa8c0c0f64b766d4a75842c1653b2a1a76c3a0ce1c'; + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if tiers mismatch signed values', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(5, 1); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature, + [5, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if sender is not the creator for which the signature was generated', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + otherWallet, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + + const signature = await generateMultipleMintSignature( + otherWallet.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if tiers, amounts and metadatahashes are not of the same length', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + additionalMetadataHash, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + [...metadataHashes, additionalMetadataHash] + ); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + [...metadataHashes, additionalMetadataHash] + ) + ).to.be.revertedWith('AssetCreate: Arrays must be same length'); + }); + it('should revert if amounts mismatch signed values', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [2, 1], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if metadataHashes mismatch signed values', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + additionalMetadataHash, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + [metadataHashes[1], additionalMetadataHash] + ) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it('should revert if signature has already been used', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 1); + await mintCatalyst(4, 1); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('AssetCreate: Invalid signature'); + }); + it("should revert if user doesn't have enough catalysts", async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + user, + } = await runCreateTestSetup(); + await mintCatalyst(4, 1); + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature, + [3, 4], + [1, 1], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('ERC1155: burn amount exceeds totalSupply'); + }); + it('should NOT allow minting with the same metadataHash twice', async function () { + const { + mintMultipleAssets, + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 6); + await mintCatalyst(4, 10); + + const signature1 = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + + await mintMultipleAssets( + signature1, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + const signature2 = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + await expect( + mintMultipleAssets( + signature2, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ) + ).to.be.revertedWith('Asset: Hash already used'); + }); + }); + describe('Event', function () { + it('should emit an AssetBatchMinted event', async function () { + const { + generateMultipleMintSignature, + mintCatalyst, + metadataHashes, + AssetCreateContract, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 3); + await mintCatalyst(4, 5); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + await expect( + AssetCreateContract.createMultipleAssets( + signature, + [3, 4], + [3, 5], + [true, true], + metadataHashes, + user.address + ) + ).to.emit(AssetCreateContract, 'AssetBatchMinted'); + }); + it('should emit AssetBatchMinted event with the correct data', async function () { + const { + generateMultipleMintSignature, + mintCatalyst, + mintMultipleAssets, + metadataHashes, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 3); + await mintCatalyst(4, 5); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + const result = await mintMultipleAssets( + signature, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + const eventData = result.events.filter( + (e: Event) => e.event == 'AssetBatchMinted' + )[0].args; + + // creator should be user + expect(eventData.creator).to.equal(user.address); + // tiers should be [3, 4] + expect(eventData.tiers[0]).to.equal(3); + expect(eventData.tiers[1]).to.equal(4); + // amounts should be [3, 5] + expect(eventData.amounts[0]).to.equal(3); + expect(eventData.amounts[1]).to.equal(5); + // metadataHashes should be metadataHashes + expect(eventData.metadataHashes[0]).to.equal(metadataHashes[0]); + expect(eventData.metadataHashes[1]).to.equal(metadataHashes[1]); + // revealed should be [true, true] + expect(eventData.revealed[0]).to.be.true; + expect(eventData.revealed[1]).to.be.true; + }); + it('should emit catalyst burn event', async function () { + const { + generateMultipleMintSignature, + mintCatalyst, + + metadataHashes, + AssetCreateContractAsUser, + CatalystContract, + user, + } = await runCreateTestSetup(); + await mintCatalyst(3, 3); + await mintCatalyst(4, 5); + + const signature = await generateMultipleMintSignature( + user.address, + [3, 4], + [3, 5], + [true, true], + metadataHashes + ); + await expect( + AssetCreateContractAsUser.createMultipleAssets( + signature, + [3, 4], + [3, 5], + [true, true], + metadataHashes, + user.address + ) + ).to.emit(CatalystContract, 'TransferBatch'); + }); + }); + }); + describe('Special asset mint', function () { + describe('Success', function () { + it('should allow special minter role to mint special assets with tier 0 (TSB Exclusive)', async function () { + const { + mintSpecialAsset, + generateSingleMintSignature, + user, + metadataHashes, + grantSpecialMinterRole, + } = await runCreateTestSetup(); + + await grantSpecialMinterRole(user.address); + const signature = await generateSingleMintSignature( + user.address, + 0, + 1, + true, + metadataHashes[0] + ); + await expect(mintSpecialAsset(signature, 1, metadataHashes[0])).to.not + .be.reverted; + }); + }); + describe('Revert', function () { + it('should NOT ALLOW unauthorized wallets to mint special assets', async function () { + const { + mintSpecialAsset, + generateSingleMintSignature, + user, + metadataHashes, + } = await runCreateTestSetup(); + + const signature = await generateSingleMintSignature( + user.address, + 0, + 1, + true, + metadataHashes[0] + ); + await expect( + mintSpecialAsset(signature, 1, metadataHashes[0]) + ).to.be.revertedWith( + `AccessControl: account ${user.address.toLocaleLowerCase()} is missing role 0xb696df569c2dfecb5a24edfd39d7f55b0f442be14350cbc68dbe8eb35489d3a6` + ); + }); + }); + describe('Event', function () { + it('should emit a SpecialAssetMinted event', async function () { + const { + generateSingleMintSignature, + user, + metadataHashes, + AssetCreateContractAsUser, + grantSpecialMinterRole, + AssetCreateContract, + } = await runCreateTestSetup(); + + await grantSpecialMinterRole(user.address); + const signature = await generateSingleMintSignature( + user.address, + 0, + 1, + true, + metadataHashes[0] + ); + await expect( + AssetCreateContractAsUser.createSpecialAsset( + signature, + 1, + metadataHashes[0], + user.address + ) + ).to.emit(AssetCreateContract, 'SpecialAssetMinted'); + }); + it('should emit SpecialAssetMinted event with the correct data', async function () { + const { + mintSpecialAsset, + generateSingleMintSignature, + user, + metadataHashes, + grantSpecialMinterRole, + } = await runCreateTestSetup(); + + await grantSpecialMinterRole(user.address); + const signature = await generateSingleMintSignature( + user.address, + 0, + 1, + true, + metadataHashes[0] + ); + const result = await mintSpecialAsset(signature, 1, metadataHashes[0]); + const eventData = result.events.filter( + (e: Event) => e.event == 'SpecialAssetMinted' + )[0].args; + + // creator should be user + expect(eventData.creator).to.equal(user.address); + // tier should be 1 + expect(eventData.tier).to.equal(0); + // amount should be 1 + expect(eventData.amount).to.equal(1); + // metadataHash should be metadataHashes[0] + expect(eventData.metadataHash).to.equal(metadataHashes[0]); + // revealed should be true + expect(eventData.revealed).to.be.true; + }); + }); + }); +}); diff --git a/packages/asset/test/AssetReveal.test.ts b/packages/asset/test/AssetReveal.test.ts new file mode 100644 index 0000000000..6725cf4396 --- /dev/null +++ b/packages/asset/test/AssetReveal.test.ts @@ -0,0 +1,1534 @@ +import {expect} from 'chai'; +import {formatBytes32String} from 'ethers/lib/utils'; +import {runRevealTestSetup} from './fixtures/asset/assetRevealFixtures'; +import {ethers} from 'hardhat'; +import {BigNumber} from 'ethers'; +import {findAllEventsByName, findEventByName} from './utils/events'; + +const revealHashA = formatBytes32String('revealHashA'); +const revealHashB = formatBytes32String('revealHashB'); +const revealHashC = formatBytes32String('revealHashC'); +const revealHashD = formatBytes32String('revealHashD'); +const revealHashE = formatBytes32String('revealHashE'); +const revealHashF = formatBytes32String('revealHashF'); + +describe('AssetReveal (/packages/asset/contracts/AssetReveal.sol)', function () { + describe('General', function () { + it('Should deploy correctly', async function () { + const {AssetRevealContract} = await runRevealTestSetup(); + expect(AssetRevealContract.address).to.be.properAddress; + }); + it('Should have the asset address set correctly', async function () { + const {AssetRevealContract, AssetContract} = await runRevealTestSetup(); + const assetAddress = await AssetRevealContract.getAssetContract(); + expect(assetAddress).to.equal(AssetContract.address); + }); + it('Should have the auth validator address set correctly', async function () { + const {AssetRevealContract, AuthValidatorContract} = + await runRevealTestSetup(); + const authValidatorAddress = await AssetRevealContract.getAuthValidator(); + expect(authValidatorAddress).to.equal(AuthValidatorContract.address); + }); + it('should give DEFAULT_ADMIN_ROLE to the defaultAdmin', async function () { + const {AssetRevealContract, assetAdmin} = await runRevealTestSetup(); + const hasAdminRole = await AssetRevealContract.hasRole( + await AssetRevealContract.DEFAULT_ADMIN_ROLE(), + assetAdmin.address + ); + expect(hasAdminRole).to.equal(true); + }); + it("Should increment the reveal nonce if revealing an asset that hasn't been revealed before", async function () { + const { + generateRevealSignature, + user, + unrevealedtokenId, + revealAsset, + TokenIdUtilsContract, + } = await runRevealTestSetup(); + + const newMetadataHashes1 = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const newMetadataHashes2 = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJE', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + newMetadataHashes1, + [revealHashA] + ); + const result = await revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes1, + [revealHashA] + ); + const event = findEventByName(result.events, 'AssetRevealMint'); + expect(event).to.not.be.undefined; + const newTokenId = event?.args?.newTokenIds[0]; + const revealNonce = await TokenIdUtilsContract.getRevealNonce(newTokenId); + expect(revealNonce.toString()).to.equal('1'); + + const signature2 = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + newMetadataHashes2, + [revealHashB] + ); + const result2 = await revealAsset( + signature2, + unrevealedtokenId, + amounts, + newMetadataHashes2, + [revealHashB] + ); + + const event2 = findEventByName(result2.events, 'AssetRevealMint'); + expect(event2).to.not.be.undefined; + const newTokenId2 = event2?.args?.newTokenIds[0]; + const revealNonce2 = await TokenIdUtilsContract.getRevealNonce( + newTokenId2 + ); + + expect(revealNonce2.toString()).to.equal('2'); + }); + it('Should not increment the reveal nonce if revealing an asset that has already been revealed', async function () { + const { + generateRevealSignature, + user, + unrevealedtokenId, + revealAsset, + TokenIdUtilsContract, + } = await runRevealTestSetup(); + + const sameMetadataHash = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + sameMetadataHash, + [revealHashA] + ); + const result = await revealAsset( + signature, + unrevealedtokenId, + amounts, + sameMetadataHash, + [revealHashA] + ); + const event = findEventByName(result.events, 'AssetRevealMint'); + expect(event).to.not.be.undefined; + const newTokenId = event?.args?.newTokenIds[0]; + const revealNonce = await TokenIdUtilsContract.getRevealNonce(newTokenId); + expect(revealNonce.toString()).to.equal('1'); + + const signature2 = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + sameMetadataHash, + [revealHashB] + ); + const result2 = await revealAsset( + signature2, + unrevealedtokenId, + amounts, + sameMetadataHash, + [revealHashB] + ); + + const event2 = findEventByName(result2.events, 'AssetRevealMint'); + const newTokenId2 = event2?.args?.newTokenIds[0]; + const revealNonce2 = await TokenIdUtilsContract.getRevealNonce( + newTokenId2 + ); + + expect(revealNonce2.toString()).to.equal('1'); + }); + }); + describe('Trusted Forwarder', function () { + it('should allow to read the trusted forwarder', async function () { + const {AssetRevealContract, trustedForwarder} = + await runRevealTestSetup(); + expect(await AssetRevealContract.getTrustedForwarder()).to.be.equal( + trustedForwarder.address + ); + }); + it('should correctly check if an address is a trusted forwarder or not', async function () { + const {AssetRevealContract, trustedForwarder} = + await runRevealTestSetup(); + expect( + await AssetRevealContract.isTrustedForwarder(trustedForwarder.address) + ).to.be.true; + expect( + await AssetRevealContract.isTrustedForwarder( + ethers.constants.AddressZero + ) + ).to.be.false; + }); + it('should allow DEFAULT_ADMIN to set the trusted forwarder ', async function () { + const {AssetRevealContractAsAdmin} = await runRevealTestSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + await AssetRevealContractAsAdmin.setTrustedForwarder(randomAddress); + expect( + await AssetRevealContractAsAdmin.getTrustedForwarder() + ).to.be.equal(randomAddress); + }); + it('should not allow non DEFAULT_ADMIN to set the trusted forwarder ', async function () { + const {AssetRevealContractAsUser, user, AdminRole} = + await runRevealTestSetup(); + const randomAddress = ethers.Wallet.createRandom().address; + await expect( + AssetRevealContractAsUser.setTrustedForwarder(randomAddress) + ).to.be.revertedWith( + `AccessControl: account ${user.address.toLowerCase()} is missing role ${AdminRole}` + ); + }); + it('should return correct msgData', async function () { + const {MockAssetRevealContract} = await runRevealTestSetup(); + // call the function to satisfy the coverage only, but we don't need to check the result + await MockAssetRevealContract.msgData(); + }); + }); + describe('Pause/Unpause', function () { + it('should allow pauser to pause the contract', async function () { + const {AssetRevealContractAsAdmin} = await runRevealTestSetup(); + await AssetRevealContractAsAdmin.pause(); + expect(await AssetRevealContractAsAdmin.paused()).to.be.true; + }); + it('should not allow non pauser to pause the contract', async function () { + const {AssetRevealContractAsUser, user, PauserRole} = + await runRevealTestSetup(); + await expect(AssetRevealContractAsUser.pause()).to.be.revertedWith( + `AccessControl: account ${user.address.toLowerCase()} is missing role ${PauserRole}` + ); + }); + it('should allow pauser to unpause the contract', async function () { + const {AssetRevealContractAsAdmin} = await runRevealTestSetup(); + await AssetRevealContractAsAdmin.pause(); + await AssetRevealContractAsAdmin.unpause(); + expect(await AssetRevealContractAsAdmin.paused()).to.be.false; + }); + it('should not allow non pauser to unpause the contract', async function () { + const {AssetRevealContractAsUser, user, PauserRole} = + await runRevealTestSetup(); + await expect(AssetRevealContractAsUser.unpause()).to.be.revertedWith( + `AccessControl: account ${user.address.toLowerCase()} is missing role ${PauserRole}` + ); + }); + it('should not allow revealBurn to be called when paused', async function () { + const { + AssetRevealContractAsAdmin, + AssetRevealContractAsUser, + unrevealedtokenId, + } = await runRevealTestSetup(); + await AssetRevealContractAsAdmin.pause(); + await expect( + AssetRevealContractAsUser.revealBurn(unrevealedtokenId, 1) + ).to.be.revertedWith('Pausable: paused'); + }); + it('should not allow revealMint to be called when paused', async function () { + const { + unrevealedtokenId, + user, + generateRevealSignature, + pause, + revealAsset, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + newMetadataHashes, + [revealHashA] + ); + await pause(); + await expect( + revealAsset(signature, unrevealedtokenId, amounts, newMetadataHashes, [ + revealHashA, + ]) + ).to.be.revertedWith('Pausable: paused'); + }); + it('should not allow revealBatchMint to be called when paused', async function () { + const { + unrevealedtokenId, + user, + generateRevealSignature, + pause, + revealAsset, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + newMetadataHashes, + [revealHashA] + ); + await pause(); + await expect( + revealAsset(signature, unrevealedtokenId, amounts, newMetadataHashes, [ + revealHashA, + ]) + ).to.be.revertedWith('Pausable: paused'); + }); + it('should not allow revealBatchBurn to be called when paused', async function () { + const { + unrevealedtokenId, + user, + generateRevealSignature, + pause, + revealAsset, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + newMetadataHashes, + [revealHashA] + ); + await pause(); + await expect( + revealAsset(signature, unrevealedtokenId, amounts, newMetadataHashes, [ + revealHashA, + ]) + ).to.be.revertedWith('Pausable: paused'); + }); + it('should not allow burnAndReveal to be called when paused', async function () { + const { + AssetRevealContractAsAdmin, + unrevealedtokenId, + instantReveal, + generateBurnAndRevealSignature, + user, + } = await runRevealTestSetup(); + await AssetRevealContractAsAdmin.pause(); + const newMetadataHash = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + + const signature = await generateBurnAndRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHash, + [revealHashA] + ); + + await expect( + instantReveal( + signature, + unrevealedtokenId, + amounts[0], + amounts, + newMetadataHash, + [revealHashA] + ) + ).to.be.revertedWith('Pausable: paused'); + }); + }); + describe('Burning', function () { + describe('Single burn', function () { + describe('Success', function () { + it('Should be able to burn unrevealed owned assets', async function () { + const { + AssetRevealContractAsUser, + AssetContract, + unrevealedtokenId, + user, + } = await runRevealTestSetup(); + const burnTx = await AssetRevealContractAsUser.revealBurn( + unrevealedtokenId, + 1 + ); + await burnTx.wait(); + + const userBalance = await AssetContract.balanceOf( + user.address, + unrevealedtokenId + ); + expect(userBalance.toString()).to.equal('9'); + }); + }); + describe('Revert', function () { + it('Should not be able to burn amount less than one', async function () { + const {AssetRevealContractAsUser, unrevealedtokenId} = + await runRevealTestSetup(); + await expect( + AssetRevealContractAsUser.revealBurn(unrevealedtokenId, 0) + ).to.be.revertedWith('AssetReveal: Invalid amount'); + }); + it('Should not be able to burn an asset that is already revealed', async function () { + const {AssetRevealContractAsUser, revealedtokenId} = + await runRevealTestSetup(); + await expect( + AssetRevealContractAsUser.revealBurn(revealedtokenId, 1) + ).to.be.revertedWith('AssetReveal: Already revealed'); + }); + it('Should not be able to burn more than owned by the caller', async function () { + const { + user, + AssetRevealContractAsUser, + AssetContract, + unrevealedtokenId, + } = await runRevealTestSetup(); + const balance = await AssetContract.balanceOf( + user.address, + unrevealedtokenId + ); + await expect( + AssetRevealContractAsUser.revealBurn(unrevealedtokenId, balance + 1) + ).to.be.revertedWith('ERC1155: burn amount exceeds totalSupply'); + }); + it("Should not be able to burn a token that doesn't exist", async function () { + const {AssetRevealContractAsUser} = await runRevealTestSetup(); + await expect( + AssetRevealContractAsUser.revealBurn(123, 1) + ).to.be.revertedWith('ERC1155: burn amount exceeds totalSupply'); + }); + }); + }); + describe('Batch burn', function () { + describe('Success', function () { + it('Should be able to burn multiple unrevealed owned assets', async function () { + const { + AssetRevealContractAsUser, + AssetContract, + unrevealedtokenId, + unrevealedtokenId2, + user, + } = await runRevealTestSetup(); + const amountToBurn1 = 2; + const amountToBurn2 = 3; + const tk1BalanceBeforeBurn = await AssetContract.balanceOf( + user.address, + unrevealedtokenId + ); + + const tk2BalanceBeforeBurn = await AssetContract.balanceOf( + user.address, + unrevealedtokenId2 + ); + + const burnTx = await AssetRevealContractAsUser.revealBatchBurn( + [unrevealedtokenId, unrevealedtokenId2], + [amountToBurn1, amountToBurn2] + ); + await burnTx.wait(); + + const tk1BalanceAfterBurn = await AssetContract.balanceOf( + user.address, + unrevealedtokenId + ); + + const tk2BalanceAfterBurn = await AssetContract.balanceOf( + user.address, + unrevealedtokenId2 + ); + + expect(tk1BalanceBeforeBurn.sub(amountToBurn1)).to.equal( + tk1BalanceAfterBurn + ); + expect(tk2BalanceBeforeBurn.sub(amountToBurn2)).to.equal( + tk2BalanceAfterBurn + ); + }); + }); + describe('Revert', function () { + it("should revert if ids array and amounts array aren't the same length", async function () { + const {AssetRevealContractAsUser, unrevealedtokenId} = + await runRevealTestSetup(); + await expect( + AssetRevealContractAsUser.revealBatchBurn( + [unrevealedtokenId], + [1, 2] + ) + ).to.be.revertedWith('AssetReveal: Invalid input'); + }); + }); + }); + describe('Burn Events', function () { + it('Should emit AssetRevealBurn event with correct data when burning single token', async function () { + const {AssetRevealContractAsUser, unrevealedtokenId, user} = + await runRevealTestSetup(); + const burnTx = await AssetRevealContractAsUser.revealBurn( + unrevealedtokenId, + 1 + ); + const burnResult = await burnTx.wait(); + const burnEvent = findEventByName(burnResult.events, 'AssetRevealBurn'); + expect(burnEvent).to.not.be.undefined; + // revealer + expect(burnEvent?.args?.revealer).to.equal(user.address); + // token id that is being revealed + expect(burnEvent?.args?.unrevealedTokenId).to.equal(unrevealedtokenId); + // amount + expect(burnEvent?.args?.amount.toString()).to.equal('1'); + }); + it('should emit AssetRevealBatchBurn event with correct data when burning multiple tokens', async function () { + const { + AssetRevealContractAsUser, + unrevealedtokenId, + unrevealedtokenId2, + user, + } = await runRevealTestSetup(); + const burnTx = await AssetRevealContractAsUser.revealBatchBurn( + [unrevealedtokenId, unrevealedtokenId2], + [1, 2] + ); + const burnResult = await burnTx.wait(); + const burnEvent = findEventByName( + burnResult.events, + 'AssetRevealBatchBurn' + ); + expect(burnEvent).to.not.be.undefined; + // revealer + expect(burnEvent?.args?.revealer).to.equal(user.address); + // token ids that are being revealed + expect(burnEvent?.args?.unrevealedTokenIds.toString()).to.equal( + [unrevealedtokenId, unrevealedtokenId2].toString() + ); + // amount + expect(burnEvent?.args?.amounts.toString()).to.equal([1, 2].toString()); + }); + }); + }); + describe('Reveal Minting', function () { + describe('Signature generation and validation', function () { + it('Should not allow minting with invalid amount', async function () { + const { + user, + generateRevealSignature, + unrevealedtokenId, + AssetRevealContract, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + await expect( + AssetRevealContract.revealMint( + signature, + unrevealedtokenId, + [123], // invalid + newMetadataHashes, + [revealHashA] + ) + ).to.be.revertedWith('AssetReveal: Invalid signature'); + }); + it('Should not allow minting with invalid recipient', async function () { + const {revealAsset, unrevealedtokenId, generateRevealSignature} = + await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const incorrectSignature = await generateRevealSignature( + '0x0000000000000000000000000000000000000000', // invalid + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + + await expect( + revealAsset( + incorrectSignature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ) + ).to.be.revertedWith('AssetReveal: Invalid signature'); + }); + it('Should not allow minting with invalid prevTokenId', async function () { + const { + user, + generateRevealSignature, + unrevealedtokenId, + AssetRevealContract, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + + await expect( + AssetRevealContract.revealMint( + signature, + 123, // invalid + amounts, + newMetadataHashes, + [revealHashA] + ) + ).to.be.revertedWith('AssetReveal: Invalid signature'); + }); + it('Should not allow minting with invalid metadataHashes', async function () { + const {user, generateRevealSignature, unrevealedtokenId, revealAsset} = + await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + + await expect( + revealAsset( + signature, + unrevealedtokenId, + amounts, + ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJE'], // invalid + [revealHashA] + ) + ).to.be.revertedWith('AssetReveal: Invalid signature'); + }); + }); + describe('Single reveal mint', function () { + describe('Success', function () { + it('Should allow minting with valid signature', async function () { + const { + user, + unrevealedtokenId, + generateRevealSignature, + revealAsset, + AssetContract, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + + const signature = await generateRevealSignature( + user.address, // revealer + unrevealedtokenId, // prevTokenId + amounts, + newMetadataHashes, + [revealHashA] + ); + const result = await revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + const event = findEventByName(result.events, 'AssetRevealMint'); + expect(event).to.not.be.undefined; + const newTokenId = event?.args?.newTokenIds[0]; + const balance = await AssetContract.balanceOf( + user.address, + newTokenId + ); + expect(balance.toString()).to.equal('1'); + }); + it('Should allow minting when multiple copies revealed to the same metadata hash', async function () { + const { + user, + unrevealedtokenId, + AssetContract, + revealAsset, + generateRevealSignature, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [2]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + const result = await revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + const event = findEventByName(result.events, 'AssetRevealMint'); + expect(event).to.not.be.undefined; + expect(event?.args?.newTokenIds.length).to.equal(1); + const newTokenId = event?.args?.newTokenIds[0]; + const balance = await AssetContract.balanceOf( + user.address, + newTokenId + ); + expect(balance.toString()).to.equal('2'); + }); + it('should increase the tokens supply for tokens with same metadata hash', async function () { + const { + user, + unrevealedtokenId, + generateRevealSignature, + revealAsset, + AssetContract, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + const result = await revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + const event = findEventByName(result.events, 'AssetRevealMint'); + const newTokenId = event?.args?.newTokenIds[0]; + const balance = await AssetContract.balanceOf( + user.address, + newTokenId + ); + expect(balance.toString()).to.equal('1'); + const signature2 = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashB] + ); + await revealAsset( + signature2, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashB] + ); + const balance2 = await AssetContract.balanceOf( + user.address, + newTokenId + ); + expect(balance2.toString()).to.equal('2'); + }); + it('Should allow revealing multiple copies at the same time', async function () { + const { + user, + generateRevealSignature, + revealAsset, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJ1', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJ2', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJ3', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJ4', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJ5', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJ6', + ]; + const amountToMint = [1, 2, 1, 7, 1, 2]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amountToMint, + newMetadataHashes, + [ + revealHashA, + revealHashB, + revealHashC, + revealHashD, + revealHashE, + revealHashF, + ] + ); + + const result = await revealAsset( + signature, + unrevealedtokenId, + amountToMint, + newMetadataHashes, + [ + revealHashA, + revealHashB, + revealHashC, + revealHashD, + revealHashE, + revealHashF, + ] + ); + const event = findEventByName(result.events, 'AssetRevealMint'); + expect(event).to.not.be.undefined; + expect(event?.args?.newTokenIds.length).to.equal(6); + }); + it('should set the reveal hash as used after successful mint', async function () { + const { + user, + generateRevealSignature, + revealAsset, + unrevealedtokenId, + AssetRevealContract, + } = await runRevealTestSetup(); + const newMetadataHashes = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf']; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + await revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + const isUsed = await AssetRevealContract.revealHashUsed(revealHashA); + expect(isUsed).to.equal(true); + }); + }); + describe('Revert', function () { + it('Should revert if amounts array is not the same length as metadataHashes array', async function () { + const { + user, + generateRevealSignature, + revealAsset, + unrevealedtokenId, + } = await runRevealTestSetup(); + + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg', + ]; + + const amounts = [1, 2, 3]; + + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA, revealHashB] + ); + + await expect( + revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA, revealHashB] + ) + ).to.be.revertedWith('AssetReveal: 1-Array mismatch'); + }); + it('Should revert if amounts array is not the same length as revealHashes array', async function () { + const { + user, + generateRevealSignature, + revealAsset, + unrevealedtokenId, + } = await runRevealTestSetup(); + + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg', + ]; + + const amounts = [1, 2]; + + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA, revealHashB, revealHashC] + ); + + await expect( + revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA, revealHashB, revealHashC] + ) + ).to.be.revertedWith('AssetReveal: 2-Array mismatch'); + }); + it('Should not allow using the same signature twice', async function () { + const { + user, + generateRevealSignature, + revealAsset, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ); + + await expect( + revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ) + ).not.to.be.reverted; + + await expect( + revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA] + ) + ).to.be.revertedWith('AssetReveal: Hash already used'); + }); + }); + describe('Events', function () { + it('should emit AssetRevealMint event when successully revealed a token', async function () { + const { + user, + generateRevealSignature, + revealAsset, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg', + ]; + const amounts = [1, 2]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA, revealHashB] + ); + + const result = await revealAsset( + signature, + unrevealedtokenId, + amounts, + newMetadataHashes, + [revealHashA, revealHashB] + ); + const event = findEventByName(result.events, 'AssetRevealMint'); + expect(event).to.not.be.undefined; + }); + it('should emit AssetRevealMint event with correct arguments', async function () { + const { + user, + generateRevealSignature, + revealAsset, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHashes = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg', + ]; + const mintAmounts = [1, 2]; + const signature = await generateRevealSignature( + user.address, + unrevealedtokenId, + mintAmounts, + newMetadataHashes, + [revealHashA, revealHashB] + ); + + const result = await revealAsset( + signature, + unrevealedtokenId, + mintAmounts, + newMetadataHashes, + [revealHashA, revealHashB] + ); + + const event = findEventByName(result.events, 'AssetRevealMint'); + expect(event).to.not.be.undefined; + const args = event?.args; + if (!args) { + expect.fail('Event args are undefined'); + } + const { + recipient, + unrevealedTokenId, + amounts, + newTokenIds, + revealHashes, + } = args; + expect(recipient).to.equal(user.address); + expect(unrevealedTokenId).to.equal(unrevealedtokenId); + expect(amounts).to.deep.equal(mintAmounts); + expect(newTokenIds.length).to.equal(2); + expect(revealHashes).to.deep.equal([revealHashA, revealHashB]); + }); + }); + }); + describe('Batch reveal mint', function () { + describe('Success', function () { + it('Should allow batch reveal minting with valid signatures', async function () { + const { + user, + revealAssetBatch, + generateBatchRevealSignature, + unrevealedtokenId, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHashes1 = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const newMetadataHashes2 = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJZ', + ]; + const amounts1 = [1]; + const amounts2 = [1]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + + const result = await revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + + // expect one batch reveal event + const event = findEventByName(result.events, 'AssetRevealBatchMint'); + expect(event).to.not.be.undefined; + }); + it("should allow batch reveal of the same token's copies", async function () { + const { + user, + revealAssetBatch, + generateBatchRevealSignature, + unrevealedtokenId, + AssetContract, + } = await runRevealTestSetup(); + const newMetadataHashes1 = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg', + ]; + const newMetadataHashes2 = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg', + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXch', + ]; + const amounts1 = [1, 2]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId], + [amounts1, amounts1], + [newMetadataHashes1, newMetadataHashes2], + [ + [revealHashA, revealHashB], + [revealHashC, revealHashD], + ] + ); + + const result = await revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId], + [amounts1, amounts1], + [newMetadataHashes1, newMetadataHashes2], + [ + [revealHashA, revealHashB], + [revealHashC, revealHashD], + ] + ); + + const batchRevealMintEvent = findEventByName( + result.events, + 'AssetRevealBatchMint' + ); + + const newTokenIds = batchRevealMintEvent?.args?.newTokenIds; + const allNewTokenIds = newTokenIds.flat(); + + const idsAsStrings = allNewTokenIds.map((id: BigNumber) => + id.toString() + ); + + // deduplicate, deep equality + const deduplicated = [...new Set(idsAsStrings)]; + + expect(deduplicated.length).to.equal(3); + // check balances + const balance1 = await AssetContract.balanceOf( + user.address, + deduplicated[0] + ); + + const balance2 = await AssetContract.balanceOf( + user.address, + deduplicated[1] + ); + + const balance3 = await AssetContract.balanceOf( + user.address, + deduplicated[2] + ); + + expect(balance1.toString()).to.equal('1'); + expect(balance2.toString()).to.equal('3'); + expect(balance3.toString()).to.equal('2'); + }); + }); + describe('Revert', function () { + it('Should revert if ids array and amounts array are not the same length', async function () { + const { + user, + generateBatchRevealSignature, + revealAssetBatch, + unrevealedtokenId, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHashes1 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf']; + const newMetadataHashes2 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg']; + const amounts1 = [1]; + const amounts2 = [1, 2]; + const amounts3 = [1, 2]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2, amounts3], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + + await expect( + revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2, amounts3], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ) + ).to.be.revertedWith('AssetReveal: 1-Array mismatch'); + }); + it('Should revert if ids array and metadataHashes array are not the same length', async function () { + const { + user, + generateBatchRevealSignature, + revealAssetBatch, + unrevealedtokenId, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHashes1 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf']; + const amounts1 = [1]; + const amounts2 = [1]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1], + [[revealHashA], [revealHashB]] + ); + + await expect( + revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1], + [[revealHashA], [revealHashB]] + ) + ).to.be.revertedWith('AssetReveal: 2-Array mismatch'); + }); + it('Should revert if ids array and revealHashes array are not the same length', async function () { + const { + user, + generateBatchRevealSignature, + revealAssetBatch, + unrevealedtokenId, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHashes1 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf']; + const newMetadataHashes2 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg']; + const amounts1 = [1]; + const amounts2 = [1]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA]] + ); + + await expect( + revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA]] + ) + ).to.be.revertedWith('AssetReveal: 3-Array mismatch'); + }); + it('should not allow using the same signature twice', async function () { + const { + user, + generateBatchRevealSignature, + revealAssetBatch, + unrevealedtokenId, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHashes1 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf']; + const newMetadataHashes2 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg']; + const amounts1 = [1]; + const amounts2 = [1]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + + await expect( + revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ) + ).not.to.be.reverted; + + await expect( + revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ) + ).to.be.revertedWith('AssetReveal: Hash already used'); + }); + }); + describe('Events', function () { + it('should emit multiple AssetRevealBatchMint events when successully revealed multiple tokens', async function () { + const { + user, + generateBatchRevealSignature, + revealAssetBatch, + unrevealedtokenId, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHashes1 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf']; + const newMetadataHashes2 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg']; + const amounts1 = [1]; + const amounts2 = [1]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + + const result = await revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + + const revealEvents = findAllEventsByName( + result.events, + 'AssetRevealBatchMint' + ); + expect(revealEvents.length).to.equal(1); + }); + it('should emit AssetRevealBatchMint events with correct arguments when successully revealed multiple tokens', async function () { + const { + user, + generateBatchRevealSignature, + revealAssetBatch, + unrevealedtokenId, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHashes1 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcf']; + const newMetadataHashes2 = ['QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcg']; + const amounts1 = [1]; + const amounts2 = [1]; + + const signature = await generateBatchRevealSignature( + user.address, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + + const result = await revealAssetBatch( + signature, + [unrevealedtokenId, unrevealedtokenId2], + [amounts1, amounts2], + [newMetadataHashes1, newMetadataHashes2], + [[revealHashA], [revealHashB]] + ); + const revealEvents = findAllEventsByName( + result.events, + 'AssetRevealBatchMint' + ); + expect(revealEvents.length).to.equal(1); + const args = revealEvents[0].args; + + expect(args?.recipient).to.equal(user.address); + expect(args?.unrevealedTokenIds).to.deep.equal([ + unrevealedtokenId, + unrevealedtokenId2, + ]); + expect(args?.amounts).to.deep.equal([amounts1, amounts2]); + expect(args?.newTokenIds.length).to.equal(2); + expect(args?.revealHashes).to.deep.equal([ + [revealHashA], + [revealHashB], + ]); + }); + }); + }); + describe('Burn and reveal mint', function () { + describe('Success', function () { + it('Should allow instant reveal when authorized by the backend for allowed tier', async function () { + const { + user, + generateBurnAndRevealSignature, + instantReveal, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHash = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + + const signature = await generateBurnAndRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHash, + [revealHashA] + ); + + const result = await instantReveal( + signature, + unrevealedtokenId, + amounts[0], + amounts, + newMetadataHash, + [revealHashA] + ); + const revealMintEvent = findAllEventsByName( + result.events, + 'AssetRevealMint' + )[0]; + expect(revealMintEvent).to.not.be.undefined; + }); + }); + describe('Revert', function () { + it('should revert if the tier is not allowed to instant reveal', async function () { + const { + user, + generateBurnAndRevealSignature, + instantReveal, + unrevealedtokenId2, + } = await runRevealTestSetup(); + const newMetadataHash = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJF', + ]; + const amounts = [1]; + + const signature = await generateBurnAndRevealSignature( + user.address, + unrevealedtokenId2, + amounts, + newMetadataHash, + [revealHashA] + ); + + await expect( + instantReveal( + signature, + unrevealedtokenId2, + amounts[0], + amounts, + newMetadataHash, + [revealHashA] + ) + ).to.be.revertedWith('AssetReveal: Not allowed'); + }); + it("should revert if amounts array isn't the same length as metadataHashes array", async function () { + const { + user, + generateBurnAndRevealSignature, + instantReveal, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHash = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJE', + ]; + const amounts = [1, 2]; + + const signature = await generateBurnAndRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHash, + [revealHashA] + ); + + await expect( + instantReveal( + signature, + unrevealedtokenId, + amounts[0], + amounts, + newMetadataHash, + [revealHashA] + ) + ).to.be.revertedWith('AssetReveal: 1-Array mismatch'); + }); + it("should revert if amounts array isn't the same length as revealHashes array", async function () { + const { + user, + generateBurnAndRevealSignature, + instantReveal, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHash = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJE', + ]; + const amounts = [1]; + + const signature = await generateBurnAndRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHash, + [revealHashA, revealHashB] + ); + + await expect( + instantReveal( + signature, + unrevealedtokenId, + amounts[0], + amounts, + newMetadataHash, + [revealHashA, revealHashB] + ) + ).to.be.revertedWith('AssetReveal: 2-Array mismatch'); + }); + }); + describe('Events', function () { + it('Should emit AssetRevealMint event with correct data when burning and revealing a single token', async function () { + const { + user, + generateBurnAndRevealSignature, + instantReveal, + unrevealedtokenId, + } = await runRevealTestSetup(); + const newMetadataHash = [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJE', + ]; + const amounts = [1]; + + const signature = await generateBurnAndRevealSignature( + user.address, + unrevealedtokenId, + amounts, + newMetadataHash, + [revealHashA] + ); + + const result = await instantReveal( + signature, + unrevealedtokenId, + amounts[0], + amounts, + newMetadataHash, + [revealHashA] + ); + const revealMintEvent = findAllEventsByName( + result.events, + 'AssetRevealMint' + )[0]; + expect(revealMintEvent).to.not.be.undefined; + expect(revealMintEvent?.args?.['recipient']).to.equal(user.address); + expect(revealMintEvent?.args?.['unrevealedTokenId']).to.equal( + unrevealedtokenId + ); + expect(revealMintEvent?.args?.['amounts']).to.deep.equal(amounts); + expect(revealMintEvent?.args?.['newTokenIds'].length).to.equal(1); + expect(revealMintEvent?.args?.['revealHashes']).to.deep.equal([ + revealHashA, + ]); + }); + }); + }); + }); +}); diff --git a/packages/asset/test/AssetRoyalty.test.ts b/packages/asset/test/AssetRoyalty.test.ts new file mode 100644 index 0000000000..4c859d75ec --- /dev/null +++ b/packages/asset/test/AssetRoyalty.test.ts @@ -0,0 +1,979 @@ +import {ethers} from 'hardhat'; +import {expect} from 'chai'; +import {splitterAbi} from './Splitter.abi'; +import {BigNumber} from 'ethers'; +import { + generateAssetId, + assetRoyaltyDistribution, +} from './fixtures/asset/assetRoyaltyFixture'; + +describe('Asset Royalties', function () { + describe('Asset royalty distribution via splitter', function () { + it('should split ERC20 using EIP2981', async function () { + const { + Asset, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + creator, + AssetAsSeller, + RoyaltyManagerContract, + assetAsMinter, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + creator.address + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + const balance = await ERC20.balanceOf(splitter); + + expect(balance).to.be.equal(1000000 * (assetRoyaltyBPS / 10000)); + + await splitterContract + .connect(await ethers.getSigner(creator.address)) + .splitERC20Tokens(ERC20.address); + + const balanceCreator = await ERC20.balanceOf(creator.address); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceCreator).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + }); + it('should split ERC20 using EIP2981 using trusted forwarder', async function () { + const { + Asset, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + creator, + AssetAsSeller, + RoyaltyManagerContract, + assetAsMinter, + TrustedForwarder, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + creator.address + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + const balance = await ERC20.balanceOf(splitter); + + expect(balance).to.be.equal(1000000 * (assetRoyaltyBPS / 10000)); + + const data = await splitterContract + .connect(creator.address) + .populateTransaction['splitERC20Tokens(address)'](ERC20.address); + + await TrustedForwarder.execute({...data, value: BigNumber.from(0)}); + + const balanceCreator = await ERC20.balanceOf(creator.address); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceCreator).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + }); + + it('should revert split ERC20 using EIP2981 using non trusted forwarder', async function () { + const { + Asset, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + creator, + AssetAsSeller, + RoyaltyManagerContract, + assetAsMinter, + NonTrustedForwarder, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + creator.address + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + const balance = await ERC20.balanceOf(splitter); + + expect(balance).to.be.equal(1000000 * (assetRoyaltyBPS / 10000)); + + const data = await splitterContract + .connect(creator.address) + .populateTransaction['splitERC20Tokens(address)'](ERC20.address); + + await expect( + NonTrustedForwarder.execute({...data, value: BigNumber.from(0)}) + ).to.be.revertedWith('Call execution failed'); + + const balanceCreator = await ERC20.balanceOf(creator.address); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + const newbalance = await ERC20.balanceOf(splitter); + + expect(newbalance).to.be.equal(1000000 * (assetRoyaltyBPS / 10000)); + + expect(balanceCreator).to.be.equal(0); + expect(balanceCommonRoyaltyReceiver).to.be.equal(0); + }); + + it('should get trusted forwarder from Royalty Manager', async function () { + const {RoyaltyManagerContract, TrustedForwarder} = + await assetRoyaltyDistribution(); + + expect(await RoyaltyManagerContract.getTrustedForwarder()).to.be.equal( + TrustedForwarder.address + ); + }); + + it('should split ERC20 using RoyaltyEngine', async function () { + const { + Asset, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + creator, + AssetAsSeller, + assetAsMinter, + RoyaltyManagerContract, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true + ); + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + const balanceCreator = await ERC20.balanceOf(creator.address); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceCreator).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + }); + + it('should split ETH using EIP2981', async function () { + const { + Asset, + ERC20, + mockMarketplace, + seller, + buyer, + commonRoyaltyReceiver, + creator, + user, + AssetAsSeller, + assetAsMinter, + RoyaltyManagerContract, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + const balanceCreator = await ethers.provider.getBalance(creator.address); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + const value = ethers.utils.parseUnits('1000', 'ether'); + await mockMarketplace + .connect(user) + .distributeRoyaltyEIP2981( + 0, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceCreatorNew = await ethers.provider.getBalance( + creator.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceCreatorNew.sub(balanceCreator)).to.be.equal( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + expect( + balanceCreatorNew + .sub(balanceCreator) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value.mul(BigNumber.from(assetRoyaltyBPS)).div(BigNumber.from(10000)) + ); + }); + + it('should split ETH using RoyaltyEngine', async function () { + const { + Asset, + ERC20, + mockMarketplace, + seller, + buyer, + commonRoyaltyReceiver, + creator, + user, + AssetAsSeller, + assetAsMinter, + RoyaltyManagerContract, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + await Asset.connect(seller).setApprovalForAll( + mockMarketplace.address, + true + ); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + const balanceCreator = await ethers.provider.getBalance(creator.address); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + const value = ethers.utils.parseUnits('1000', 'ether'); + await mockMarketplace + .connect(user) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceCreatorNew = await ethers.provider.getBalance( + creator.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceCreatorNew.sub(balanceCreator)).to.be.equal( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + expect( + balanceCreatorNew + .sub(balanceCreator) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value.mul(BigNumber.from(assetRoyaltyBPS)).div(BigNumber.from(10000)) + ); + }); + + it('creator should receive Royalty in ETH to new address set by the creator', async function () { + const { + Asset, + ERC20, + mockMarketplace, + AssetAsSeller, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + creator, + user, + RoyaltyManagerContract, + assetAsMinter, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + creator.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + expect(await splitterContract.recipient()).to.be.equal(creator.address); + + const tnx = await RoyaltyManagerContract.connect( + await ethers.getSigner(creator.address) + ).setRoyaltyRecipient(royaltyReceiver.address); + + await tnx.wait(); + + expect(await splitterContract.recipient()).to.be.equal( + royaltyReceiver.address + ); + + const balanceRoyaltyReceiver = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + const value = ethers.utils.parseUnits('1000', 'ether'); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(user) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiverNew = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiverNew.sub(balanceRoyaltyReceiver)).to.be.equal( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + expect( + balanceRoyaltyReceiverNew + .sub(balanceRoyaltyReceiver) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value.mul(BigNumber.from(assetRoyaltyBPS)).div(BigNumber.from(10000)) + ); + }); + + it('common share of royalty should be received in ETH to new address set by the Admin on RoyaltyManagerContract contract', async function () { + const { + Asset, + ERC20, + mockMarketplace, + commonRoyaltyReceiver2, + RoyaltyManagerAsAdmin, + seller, + buyer, + commonRoyaltyReceiver, + creator, + user, + AssetAsSeller, + assetAsMinter, + RoyaltyManagerContract, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver.address + ); + + await RoyaltyManagerAsAdmin.setRecipient(commonRoyaltyReceiver2.address); + + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver2.address + ); + + const balanceCreator = await ethers.provider.getBalance(creator.address); + const balanceCommonRoyaltyReceiver2 = await ethers.provider.getBalance( + commonRoyaltyReceiver2.address + ); + const value = ethers.utils.parseUnits('1000', 'ether'); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(user) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceCreatorNew = await ethers.provider.getBalance( + creator.address + ); + const balanceCommonRoyaltyReceiver2New = await ethers.provider.getBalance( + commonRoyaltyReceiver2.address + ); + + expect(balanceCreatorNew.sub(balanceCreator)).to.be.equal( + balanceCommonRoyaltyReceiver2New.sub(balanceCommonRoyaltyReceiver2) + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + expect( + balanceCreatorNew + .sub(balanceCreator) + .add( + balanceCommonRoyaltyReceiver2New.sub(balanceCommonRoyaltyReceiver2) + ) + ).to.be.equal( + value.mul(BigNumber.from(assetRoyaltyBPS)).div(BigNumber.from(10000)) + ); + }); + + it('common share of Royalty should be received in ETH with new splits set by the owner on registry', async function () { + const { + Asset, + ERC20, + mockMarketplace, + AssetAsSeller, + RoyaltyManagerAsAdmin, + seller, + buyer, + commonRoyaltyReceiver, + creator, + user, + assetAsMinter, + RoyaltyManagerContract, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + + await RoyaltyManagerAsAdmin.setSplit(6000); + const balanceCreator = await ethers.provider.getBalance(creator.address); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + const value = ethers.utils.parseUnits('1000', 'ether'); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(user) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceCreatorNew = await ethers.provider.getBalance( + creator.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + + const TotalRoyalty = value + .mul(BigNumber.from(assetRoyaltyBPS)) + .div(BigNumber.from(10000)); + + const sellerRoyaltyShare = TotalRoyalty.mul(BigNumber.from(4000)).div( + BigNumber.from(10000) + ); + + const commonRecipientShare = TotalRoyalty.mul(BigNumber.from(6000)).div( + BigNumber.from(10000) + ); + + expect(balanceCreatorNew.sub(balanceCreator)).to.be.equal( + sellerRoyaltyShare + ); + + expect( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ).to.be.equal(commonRecipientShare); + + expect( + balanceCreatorNew + .sub(balanceCreator) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value.mul(BigNumber.from(assetRoyaltyBPS)).div(BigNumber.from(10000)) + ); + }); + + it('creator should receive Royalty in ERC20 to new address royalty recipient address set by them', async function () { + const { + Asset, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + AssetAsSeller, + RoyaltyManagerContract, + creator, + assetAsMinter, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + creator.address + ); + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + expect(await splitterContract.recipient()).to.be.equal(creator.address); + const tnx = await RoyaltyManagerContract.connect( + await ethers.getSigner(creator.address) + ).setRoyaltyRecipient(royaltyReceiver.address); + + await tnx.wait(); + + expect(await splitterContract.recipient()).to.be.equal( + royaltyReceiver.address + ); + + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true + ); + + await splitterContract + .connect(await ethers.getSigner(royaltyReceiver.address)) + .splitERC20Tokens(ERC20.address); + const balanceCreator = await ERC20.balanceOf(creator.address); + expect(balanceCreator).to.be.equal(0); + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + }); + + it('common share of royalty should be received in ERC20 to new address set by the Admin on RoyaltyManager contract', async function () { + const { + Asset, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + RoyaltyManagerAsAdmin, + commonRoyaltyReceiver2, + commonRoyaltyReceiver, + creator, + AssetAsSeller, + assetAsMinter, + RoyaltyManagerContract, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver.address + ); + await RoyaltyManagerAsAdmin.setRecipient(commonRoyaltyReceiver2.address); + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver2.address + ); + + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + const balanceCommonRoyaltyReceiver2 = await ERC20.balanceOf( + commonRoyaltyReceiver2.address + ); + const balanceCreator = await ERC20.balanceOf(creator.address); + expect(balanceCreator).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver2).to.be.equal( + (1000000 * (assetRoyaltyBPS / 10000)) / 2 + ); + }); + + it('common recipient should receive Royalty in ERC20 with new splits set by the owner on registry', async function () { + const { + Asset, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + RoyaltyManagerAsAdmin, + AssetAsSeller, + commonRoyaltyReceiver, + creator, + assetAsMinter, + RoyaltyManagerContract, + } = await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + await RoyaltyManagerAsAdmin.setSplit(6000); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await AssetAsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await Asset.balanceOf(seller.address, id)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + Asset.address, + id, + buyer.address, + seller.address, + true + ); + + const assetRoyaltyBPS = await RoyaltyManagerContract.getContractRoyalty( + Asset.address + ); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + const balanceCreator = await ERC20.balanceOf(creator.address); + expect(balanceCreator).to.be.equal( + ((1000000 * (assetRoyaltyBPS / 10000)) / 5) * 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + ((1000000 * (assetRoyaltyBPS / 10000)) / 5) * 3 + ); + }); + }); + + describe('Roles on Asset and Manager contract', function () { + it('creator could change the recipient for his splitter', async function () { + const {seller, RoyaltyManagerContract, creator, assetAsMinter} = + await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + creator.address + ); + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + expect(await splitterContract.recipient()).to.be.equal(creator.address); + const tnx = await RoyaltyManagerContract.connect( + await ethers.getSigner(creator.address) + ).setRoyaltyRecipient(seller.address); + await tnx.wait(); + expect(await splitterContract.recipient()).to.be.equal(seller.address); + }); + + it('only creator could change the recipient for his splitter', async function () { + const {seller, RoyaltyManagerContract, deployer, creator, assetAsMinter} = + await assetRoyaltyDistribution(); + + const id = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + await expect( + RoyaltyManagerContract.connect(deployer).setRoyaltyRecipient( + seller.address + ) + ).to.revertedWith('Manager: No splitter deployed for the creator'); + }); + + it('RoyaltyManagerContract admin can set common royalty recipient', async function () { + const {seller, commonRoyaltyReceiver, RoyaltyManagerAsAdmin} = + await assetRoyaltyDistribution(); + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver.address + ); + await RoyaltyManagerAsAdmin.setRecipient(seller.address); + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + seller.address + ); + }); + + it('RoyaltyManagerContract admin can set common split', async function () { + const {RoyaltyManagerAsAdmin} = await assetRoyaltyDistribution(); + expect(await RoyaltyManagerAsAdmin.commonSplit()).to.be.equal(5000); + await RoyaltyManagerAsAdmin.setSplit(3000); + expect(await RoyaltyManagerAsAdmin.commonSplit()).to.be.equal(3000); + }); + + it('Only RoyaltyManagerContract admin can set common royalty recipient', async function () { + const {seller, RoyaltyManagerContract, managerAdminRole} = + await assetRoyaltyDistribution(); + await expect( + RoyaltyManagerContract.connect(seller).setRecipient(seller.address) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLocaleLowerCase()} is missing role ${managerAdminRole}` + ); + }); + + it('Only RoyaltyManagerContract admin can set common split', async function () { + const {seller, RoyaltyManagerContract, managerAdminRole} = + await assetRoyaltyDistribution(); + await expect( + RoyaltyManagerContract.connect(seller).setSplit(3000) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLocaleLowerCase()} is missing role ${managerAdminRole}` + ); + }); + }); + + describe('Minting', function () { + it('should have same splitter address for tokens minted by same creator.address', async function () { + const {Asset, seller, creator, assetAsMinter} = + await assetRoyaltyDistribution(); + + const id1 = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id1, 1, '0x'); + const splitter1 = await Asset.getTokenRoyaltiesSplitter(id1); + const id2 = generateAssetId(creator.address, 2); + await assetAsMinter.mint(seller.address, id2, 1, '0x01'); + const splitter2 = await Asset.getTokenRoyaltiesSplitter(id2); + expect(splitter1).to.be.equal(splitter2); + }); + + it('should not have same splitter address for tokens with minted by different creator.address', async function () { + const {Asset, seller, deployer, creator, assetAsMinter} = + await assetRoyaltyDistribution(); + + const id1 = generateAssetId(creator.address, 1); + await assetAsMinter.mint(seller.address, id1, 1, '0x'); + const splitter1 = await Asset.getTokenRoyaltiesSplitter(id1); + const id2 = generateAssetId(deployer.address, 2); + await assetAsMinter.mint(seller.address, id2, 1, '0x01'); + const splitter2 = await Asset.getTokenRoyaltiesSplitter(id2); + expect(splitter1).to.not.be.equal(splitter2); + }); + + it('should have same splitter address for tokens minted by same creator.address in batch mint', async function () { + const {Asset, seller, creator, assetAsMinter} = + await assetRoyaltyDistribution(); + + const id1 = generateAssetId(creator.address, 1); + const id2 = generateAssetId(creator.address, 2); + await assetAsMinter.mintBatch( + seller.address, + [id1, id2], + [1, 1], + ['0x', '0x01'] + ); + const splitter2 = await Asset.getTokenRoyaltiesSplitter(id2); + const splitter1 = await Asset.getTokenRoyaltiesSplitter(id1); + expect(splitter1).to.be.equal(splitter2); + }); + + it('should have different splitter address for tokens minted by same different creator.address in batch mint', async function () { + const {Asset, seller, deployer, creator, assetAsMinter} = + await assetRoyaltyDistribution(); + + const id1 = generateAssetId(creator.address, 1); + const id2 = generateAssetId(deployer.address, 2); + await assetAsMinter.mintBatch( + seller.address, + [id1, id2], + [1, 1], + ['0x', '0x01'] + ); + const splitter2 = await Asset.getTokenRoyaltiesSplitter(id2); + const splitter1 = await Asset.getTokenRoyaltiesSplitter(id1); + expect(splitter1).to.not.be.equal(splitter2); + }); + + it('should return splitter address on for a tokenId on royaltyInfo function call', async function () { + const {Asset, seller, deployer, assetAsMinter} = + await assetRoyaltyDistribution(); + + const id = generateAssetId(deployer.address, 2); + await assetAsMinter.mint(seller.address, id, 1, '0x'); + const splitter = await Asset.getTokenRoyaltiesSplitter(id); + const royaltyInfo = await Asset.royaltyInfo(id, 10000); + expect(splitter).to.be.equal(royaltyInfo[0]); + }); + }); +}); diff --git a/packages/asset/test/AuthSuperValidator.test.ts b/packages/asset/test/AuthSuperValidator.test.ts new file mode 100644 index 0000000000..b45dea5732 --- /dev/null +++ b/packages/asset/test/AuthSuperValidator.test.ts @@ -0,0 +1,159 @@ +import {ethers} from 'ethers'; +import {expect} from 'chai'; +import runSetup from './fixtures/authValidatorFixture'; + +describe('AuthSuperValidator, (/packages/asset/contracts/AuthSuperValidator.sol)', function () { + describe('General', function () { + it('should assign DEFAULT_ADMIN_ROLE to the admin address from the constructor', async function () { + const {authValidatorAdmin, AuthValidatorContract} = await runSetup(); + const DEFAULT_ADMIN_ROLE = + await AuthValidatorContract.DEFAULT_ADMIN_ROLE(); + const hasRole = await AuthValidatorContract.hasRole( + DEFAULT_ADMIN_ROLE, + authValidatorAdmin.address + ); + expect(hasRole).to.equal(true); + }); + it('should not allow DEFAULT_ADMIN_ROLE to be renounced', async function () { + const {authValidatorAdmin, AuthValidatorContract} = await runSetup(); + const DEFAULT_ADMIN_ROLE = + await AuthValidatorContract.DEFAULT_ADMIN_ROLE(); + await expect( + AuthValidatorContract.renounceRole( + DEFAULT_ADMIN_ROLE, + authValidatorAdmin.address + ) + ).to.be.revertedWith('AuthSuperValidator: cant renounce admin role'); + }); + it('should allow admin to set signer for a given contract address', async function () { + const {MockContract, AuthValidatorContractAsAdmin, backendSigner} = + await runSetup(); + await expect( + AuthValidatorContractAsAdmin.setSigner( + MockContract.address, + backendSigner.address + ) + ).to.not.be.reverted; + const assignedSigner = await AuthValidatorContractAsAdmin.getSigner( + MockContract.address + ); + expect(assignedSigner).to.equal(backendSigner.address); + }); + it('should not allow non-admin to set signer for a given contract address', async function () { + const {MockContract, AuthValidatorContract, backendSigner, deployer} = + await runSetup(); + const DEFAULT_ADMIN_ROLE = + await AuthValidatorContract.DEFAULT_ADMIN_ROLE(); + await expect( + AuthValidatorContract.setSigner( + MockContract.address, + backendSigner.address + ) + ).to.be.revertedWith( + `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}` + ); + }); + it('should allow admin to remove signer for a given contract address', async function () { + const {MockContract, AuthValidatorContractAsAdmin, backendSigner} = + await runSetup(); + await AuthValidatorContractAsAdmin.setSigner( + MockContract.address, + backendSigner.address + ); + await AuthValidatorContractAsAdmin.setSigner( + MockContract.address, + ethers.constants.AddressZero + ); + const assignedSigner = await AuthValidatorContractAsAdmin.getSigner( + MockContract.address + ); + expect(assignedSigner).to.equal(ethers.constants.AddressZero); + }); + it('should not allow non-admin to remove signer for a given contract address', async function () { + const { + MockContract, + AuthValidatorContract, + AuthValidatorContractAsAdmin, + backendSigner, + deployer, + } = await runSetup(); + const DEFAULT_ADMIN_ROLE = + await AuthValidatorContract.DEFAULT_ADMIN_ROLE(); + await AuthValidatorContractAsAdmin.setSigner( + MockContract.address, + backendSigner.address + ); + await expect( + AuthValidatorContract.setSigner( + MockContract.address, + ethers.constants.AddressZero + ) + ).to.be.revertedWith( + `AccessControl: account ${deployer.address.toLowerCase()} is missing role ${DEFAULT_ADMIN_ROLE}` + ); + }); + }); + describe('Signature verification', function () { + it('should correctly verify signature when a signer is set', async function () { + const { + AuthValidatorContractAsAdmin, + backendSigner, + authValidatorAdmin, + createMockSignature, + } = await runSetup(); + await AuthValidatorContractAsAdmin.setSigner( + authValidatorAdmin.address, + backendSigner.address + ); + const {signature, digest} = await createMockSignature( + authValidatorAdmin.address, + backendSigner + ); + const isValid = await AuthValidatorContractAsAdmin.verify( + signature, + digest + ); + expect(isValid).to.equal(true); + }); + it('should revert when signature is not valid', async function () { + const { + AuthValidatorContractAsAdmin, + backendSigner, + authValidatorAdmin, + createMockSignature, + createMockDigest, + } = await runSetup(); + await AuthValidatorContractAsAdmin.setSigner( + authValidatorAdmin.address, + backendSigner.address + ); + + // digest is using different address on purpose + const digest = createMockDigest(backendSigner.address); + const {signature} = await createMockSignature( + authValidatorAdmin.address, + backendSigner + ); + const isValid = await AuthValidatorContractAsAdmin.verify( + signature, + digest + ); + expect(isValid).to.equal(false); + }); + it('should revert when there is no signer assigned for a given contract address', async function () { + const { + AuthValidatorContractAsAdmin, + createMockSignature, + authValidatorAdmin, + backendSigner, + } = await runSetup(); + const {signature, digest} = await createMockSignature( + authValidatorAdmin.address, + backendSigner + ); + await expect( + AuthValidatorContractAsAdmin.verify(signature, digest) + ).to.be.revertedWith('AuthSuperValidator: No signer'); + }); + }); +}); diff --git a/packages/asset/test/Catalyst.test.ts b/packages/asset/test/Catalyst.test.ts new file mode 100644 index 0000000000..154892e1ea --- /dev/null +++ b/packages/asset/test/Catalyst.test.ts @@ -0,0 +1,1959 @@ +import {expect} from 'chai'; +import {setupOperatorFilter} from './fixtures/operatorFilterFixture'; +import {ethers, upgrades} from 'hardhat'; +import {runCatalystSetup} from './fixtures/catalyst/catalystFixture'; +import {CATALYST_BASE_URI, CATALYST_IPFS_CID_PER_TIER} from '../data/constants'; +import { + AccessControlInterfaceId, + ERC1155InterfaceId, + ERC1155MetadataURIInterfaceId, + ERC165InterfaceId, + ERC2981InterfaceId, +} from './utils/interfaceIds'; +import {BigNumber} from 'ethers'; + +const catalystArray = [0, 1, 2, 3, 4, 5, 6]; +const zeroAddress = '0x0000000000000000000000000000000000000000'; + +describe('Catalyst (/packages/asset/contracts/Catalyst.sol)', function () { + describe('Contract setup', function () { + it('Should deploy correctly', async function () { + const { + catalyst, + trustedForwarder, + catalystAdmin, + catalystMinter, + catalystAdminRole, + minterRole, + } = await runCatalystSetup(); + expect(await catalyst.getTrustedForwarder()).to.be.equal( + trustedForwarder.address + ); + expect( + await catalyst.hasRole(catalystAdminRole, catalystAdmin.address) + ).to.be.equals(true); + expect( + await catalyst.hasRole(minterRole, catalystMinter.address) + ).to.be.equals(true); + expect(await catalyst.highestTierIndex()).to.be.equals(6); + expect(catalyst.address).to.be.properAddress; + }); + describe('Interface support', function () { + it('should support ERC165', async function () { + const {catalyst} = await runCatalystSetup(); + expect(await catalyst.supportsInterface(ERC165InterfaceId)).to.be.true; + }); + it('should support ERC1155', async function () { + const {catalyst} = await runCatalystSetup(); + expect(await catalyst.supportsInterface(ERC1155InterfaceId)).to.be.true; + }); + it('should support ERC1155MetadataURI', async function () { + const {catalyst} = await runCatalystSetup(); + expect(await catalyst.supportsInterface(ERC1155MetadataURIInterfaceId)) + .to.be.true; + }); + it('should support AccessControl', async function () { + const {catalyst} = await runCatalystSetup(); + expect(await catalyst.supportsInterface(AccessControlInterfaceId)).to.be + .true; + }); + it('should support IERC2981', async function () { + const {catalyst} = await runCatalystSetup(); + expect(await catalyst.supportsInterface(ERC2981InterfaceId)).to.be.true; + }); + }); + it("base uri can't be empty in initialization", async function () { + const { + trustedForwarder, + catalystAdmin, + catalystMinter, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + } = await runCatalystSetup(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + + await expect( + upgrades.deployProxy( + CatalystFactory, + [ + '', + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ) + ).to.revertedWith('Catalyst: URI empty'); + }); + it("trusted forwarder can't be zero in initialization", async function () { + const { + catalystAdmin, + catalystMinter, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + } = await runCatalystSetup(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + + await expect( + upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + zeroAddress, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ) + ).to.revertedWith('Catalyst: 1-Zero address'); + }); + it("subscription can't be zero in initialization", async function () { + const { + trustedForwarder, + catalystAdmin, + catalystMinter, + RoyaltyManagerContract, + } = await runCatalystSetup(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + + await expect( + upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + zeroAddress, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ) + ).to.revertedWith('Catalyst: 2-Zero address'); + }); + it("admin can't be zero in initialization", async function () { + const { + trustedForwarder, + catalystMinter, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + } = await runCatalystSetup(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + + await expect( + upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + zeroAddress, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ) + ).to.revertedWith('Catalyst: 3-Zero address'); + }); + it("royalty manager can't be zero in initialization", async function () { + const { + trustedForwarder, + catalystAdmin, + catalystMinter, + OperatorFilterSubscriptionContract, + } = await runCatalystSetup(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + + await expect( + upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, + catalystMinter.address, + CATALYST_IPFS_CID_PER_TIER, + zeroAddress, + ], + { + initializer: 'initialize', + } + ) + ).to.revertedWith('Catalyst: 5-Zero address'); + }); + it("minter can't be zero in initialization", async function () { + const { + trustedForwarder, + catalystAdmin, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + } = await runCatalystSetup(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + + await expect( + upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + zeroAddress, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ) + ).to.revertedWith('Catalyst: 4-Zero address'); + }); + it("token CID can't be zero in initialization", async function () { + const { + trustedForwarder, + catalystAdmin, + catalystMinter, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + } = await runCatalystSetup(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + + await expect( + upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, + catalystMinter.address, + [''], + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ) + ).to.revertedWith('Catalyst: CID cant be empty'); + }); + }); + describe('Admin Role', function () { + it('Admin can set minter', async function () { + const {catalystAsAdmin, user1, minterRole} = await runCatalystSetup(); + await catalystAsAdmin.grantRole(minterRole, user1.address); + expect( + await catalystAsAdmin.hasRole(minterRole, user1.address) + ).to.be.equal(true); + }); + it('only Admin can set minter', async function () { + const {catalyst, user1, minterRole, catalystAdminRole} = + await runCatalystSetup(); + + await expect( + catalyst.connect(user1).grantRole(minterRole, user1.address) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${catalystAdminRole}` + ); + }); + it('Admin can remove minter', async function () { + const {catalystAsAdmin, minterRole, catalystMinter} = + await runCatalystSetup(); + expect( + await catalystAsAdmin.hasRole(minterRole, catalystMinter.address) + ).to.be.equal(true); + await catalystAsAdmin.revokeRole(minterRole, catalystMinter.address); + expect( + await catalystAsAdmin.hasRole(minterRole, catalystMinter.address) + ).to.be.equal(false); + }); + it('only Admin can remove minter', async function () { + const {catalyst, user1, minterRole, catalystAdminRole, catalystMinter} = + await runCatalystSetup(); + + await expect( + catalyst.connect(user1).revokeRole(minterRole, catalystMinter.address) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${catalystAdminRole}` + ); + }); + it('Admin can add new catalyst', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + await catalystAsAdmin.addNewCatalystType('0x01'); + expect(await catalystAsAdmin.uri(7)).to.be.equal('ipfs://0x01'); + }); + it('correctly increases highest tier index on adding new catalyst', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + expect(await catalystAsAdmin.highestTierIndex()).to.be.equal(6); + await catalystAsAdmin.addNewCatalystType('0x01'); + expect(await catalystAsAdmin.highestTierIndex()).to.be.equal(7); + }); + it('emits NewCatalystTypeAdded event on adding new catalyst with id one higher than the previous highest tier', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + expect(await catalystAsAdmin.highestTierIndex()).to.be.equal(6); + await expect(catalystAsAdmin.addNewCatalystType('0x01')) + .to.emit(catalystAsAdmin, 'NewCatalystTypeAdded') + .withArgs(7); + }); + it('sets the URI for newly created catalyst tier correctly', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + expect(await catalystAsAdmin.highestTierIndex()).to.be.equal(6); + await catalystAsAdmin.addNewCatalystType('0x01'); + expect(await catalystAsAdmin.uri(7)).to.be.equal('ipfs://0x01'); + }); + it('only Admin can add new catalyst', async function () { + const {catalyst, user1, catalystAdminRole} = await runCatalystSetup(); + + await expect( + catalyst.connect(user1).addNewCatalystType('0x01') + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${catalystAdminRole}` + ); + }); + it('Admin can set trusted forwarder', async function () { + const {catalystAsAdmin, user1} = await runCatalystSetup(); + await catalystAsAdmin.setTrustedForwarder(user1.address); + expect(await catalystAsAdmin.getTrustedForwarder()).to.be.equal( + user1.address + ); + }); + it('only Admin can set trusted forwarder', async function () { + const {catalyst, user1, catalystAdminRole} = await runCatalystSetup(); + + await expect( + catalyst.connect(user1).setTrustedForwarder(user1.address) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${catalystAdminRole}` + ); + }); + it('Admin can set metadata hash', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + expect(await catalystAsAdmin.uri(1)).to.be.equal( + `ipfs://${CATALYST_IPFS_CID_PER_TIER[0]}` + ); + await catalystAsAdmin.setMetadataHash(1, '0x01'); + expect(await catalystAsAdmin.uri(1)).to.be.equal('ipfs://0x01'); + }); + it('only Admin can set metadata hash', async function () { + const {catalyst, user1, catalystAdminRole} = await runCatalystSetup(); + + await expect( + catalyst.connect(user1).setMetadataHash(1, '0x01') + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${catalystAdminRole}` + ); + }); + it('Admin can set base uri', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + expect(await catalystAsAdmin.uri(1)).to.be.equal( + `ipfs://${CATALYST_IPFS_CID_PER_TIER[0]}` + ); + await catalystAsAdmin.setBaseURI('ipfs////'); + expect(await catalystAsAdmin.uri(1)).to.be.equal( + `ipfs////${CATALYST_IPFS_CID_PER_TIER[0]}` + ); + }); + it('empty base uri cant be set ', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + await expect(catalystAsAdmin.setBaseURI('')).to.be.revertedWith( + 'Catalyst: URI empty' + ); + }); + it('only Admin can set base uri', async function () { + const {catalyst, user1, catalystAdminRole} = await runCatalystSetup(); + + await expect( + catalyst.connect(user1).setBaseURI('ipfs////') + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${catalystAdminRole}` + ); + }); + it('emits BaseURISet event on setting base uri', async function () { + const {catalystAsAdmin, catalyst} = await runCatalystSetup(); + + const setBaseURITx = await catalystAsAdmin.setBaseURI('ipfs////'); + await expect(setBaseURITx) + .to.emit(catalyst, 'BaseURISet') + .withArgs(`ipfs////`); + }); + it('cant add invalid token uri', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + await expect(catalystAsAdmin.addNewCatalystType('')).to.be.revertedWith( + 'Catalyst: CID cant be empty' + ); + }); + it('cant set invalid trusted forwarder', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + await expect( + catalystAsAdmin.setTrustedForwarder(zeroAddress) + ).to.be.revertedWith('Catalyst: Zero address'); + }); + it('cant set metadata hash for invalid catalyst', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + await expect( + catalystAsAdmin.setMetadataHash(0, '0x01') + ).to.be.revertedWith('Catalyst: invalid catalyst id'); + }); + it('cant set empty metadata hash', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + await expect(catalystAsAdmin.setMetadataHash(1, '')).to.be.revertedWith( + 'Catalyst: Metadata hash empty' + ); + }); + it('cant set invalid base uri', async function () { + const {catalystAsAdmin} = await runCatalystSetup(); + await expect(catalystAsAdmin.setBaseURI('')).to.be.revertedWith( + 'Catalyst: URI empty' + ); + }); + }); + describe('Mint Token', function () { + it('minter can mint', async function () { + const {catalystAsMinter, user1} = await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 6, 2); + expect(await catalystAsMinter.balanceOf(user1.address, 6)).to.be.equal(2); + }); + it('Non minter cannot mint', async function () { + const {catalyst, user2, user1, minterRole} = await runCatalystSetup(); + await expect( + catalyst.connect(user1).mint(user2.address, 1, 1) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${minterRole}` + ); + }); + + it('Cannot mint invalid catalyst Id', async function () { + const {catalystAsMinter, user1} = await runCatalystSetup(); + await expect( + catalystAsMinter.mint(user1.address, 7, 1) + ).to.be.revertedWith('Catalyst: invalid catalyst id'); + }); + it('Minter can batch mint token', async function () { + const {catalyst, user1, catalystAsMinter} = await runCatalystSetup(); + const catalystId = []; + const catalystAmount = []; + for (let i = 1; i < catalystArray.length; i++) { + catalystId.push(catalystArray[i]); + catalystAmount.push(catalystArray[i] * 2); + } + await catalystAsMinter.mintBatch( + user1.address, + catalystId, + catalystAmount + ); + for (let i = 1; i < catalystArray.length; i++) { + expect( + await catalyst.balanceOf(user1.address, catalystArray[i]) + ).to.be.equal(catalystArray[i] * 2); + } + }); + it('Minter can mint token', async function () { + const {catalyst, user1, catalystAsMinter} = await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 10); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(10); + }); + }); + describe('Total Supply', function () { + it('Total Supply increase on minting', async function () { + const {catalyst, user1, catalystAsMinter} = await runCatalystSetup(); + for (let i = 1; i < catalystArray.length; i++) { + expect(await catalyst.totalSupply(catalystArray[i])).to.equal(0); + await catalystAsMinter.mint(user1.address, catalystArray[i], 2); + expect(await catalyst.totalSupply(catalystArray[i])).to.be.equal(2); + } + }); + it('Total Supply increase on batch minting', async function () { + const {catalyst, user1, catalystAsMinter} = await runCatalystSetup(); + const catalystId = []; + const catalystAmount = []; + for (let i = 1; i < catalystArray.length; i++) { + catalystId.push(catalystArray[i]); + catalystAmount.push(catalystArray[i] * 2); + } + await catalystAsMinter.mintBatch( + user1.address, + catalystId, + catalystAmount + ); + for (let i = 1; i < catalystArray.length; i++) { + expect(await catalyst.totalSupply(catalystArray[i])).to.equal( + catalystArray[i] * 2 + ); + } + }); + it('Total Supply decrease on burning', async function () { + const {catalyst, user1, catalystAsBurner, catalystAsMinter} = + await runCatalystSetup(); + const catalystAmount = []; + const catalystId = []; + for (let i = 1; i < catalystArray.length; i++) { + expect(await catalyst.totalSupply(catalystArray[i])).to.be.equal(0); + catalystAmount.push(catalystArray[i] * 2); + catalystId.push(catalystArray[i]); + } + + await catalystAsMinter.mintBatch( + user1.address, + catalystId, + catalystAmount + ); + for (let i = 1; i < catalystArray.length; i++) { + expect(await catalyst.totalSupply(catalystArray[i])).to.equal( + catalystArray[i] * 2 + ); + + await catalystAsBurner.burnFrom(user1.address, catalystArray[i], 2); + expect(await catalyst.totalSupply(catalystArray[i])).to.be.equal( + catalystArray[i] * 2 - 2 + ); + } + }); + it('Total Supply decrease on batch burning', async function () { + const {catalyst, user1, catalystAsMinter, catalystAsBurner} = + await runCatalystSetup(); + for (let i = 1; i < catalystArray.length; i++) { + expect(await catalyst.totalSupply(catalystArray[i])).to.equal(0); + } + const catalystId = []; + let catalystAmount = []; + for (let i = 1; i < catalystArray.length; i++) { + catalystId.push(catalystArray[i]); + catalystAmount.push(catalystArray[i] * 2); + } + await catalystAsMinter.mintBatch( + user1.address, + catalystId, + catalystAmount + ); + for (let i = 1; i < catalystArray.length; i++) { + expect(await catalyst.totalSupply(catalystArray[i])).to.equal( + catalystArray[i] * 2 + ); + } + catalystAmount = []; + + for (let i = 1; i < catalystArray.length; i++) { + catalystAmount.push(1); + } + + await catalystAsBurner.burnBatchFrom( + user1.address, + catalystId, + catalystAmount + ); + for (let i = 1; i < catalystArray.length; i++) { + expect(await catalyst.totalSupply(catalystArray[i])).to.equal( + catalystArray[i] * 2 - 1 + ); + } + }); + }); + describe('Burn catalyst', function () { + it("minter can burn user's catalyst", async function () { + const {catalyst, user1, catalystAsMinter, catalystAsBurner} = + await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 5); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(5); + await catalystAsBurner.burnFrom(user1.address, 1, 2); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(3); + }); + it("minter can batch burn user's catalyst", async function () { + const {catalyst, user1, catalystAsMinter, catalystAsBurner} = + await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 5); + await catalystAsMinter.mint(user1.address, 2, 6); + + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(5); + expect(await catalyst.balanceOf(user1.address, 2)).to.be.equal(6); + const catalystId = [1, 2]; + const catalystAmount = [2, 2]; + await catalystAsBurner.burnBatchFrom( + user1.address, + catalystId, + catalystAmount + ); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(3); + expect(await catalyst.balanceOf(user1.address, 2)).to.be.equal(4); + }); + it('user can burn their catalyst', async function () { + const {catalyst, user1, catalystAsMinter} = await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 5); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(5); + await catalyst.connect(user1).burn(user1.address, 1, 2); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(3); + }); + it('user can batch burn their catalyst', async function () { + const {catalyst, user1, catalystAsMinter} = await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 5); + await catalystAsMinter.mint(user1.address, 2, 6); + + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(5); + expect(await catalyst.balanceOf(user1.address, 2)).to.be.equal(6); + const catalystId = [1, 2]; + const catalystAmount = [2, 2]; + await catalyst + .connect(user1) + .burnBatch(user1.address, catalystId, catalystAmount); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(3); + expect(await catalyst.balanceOf(user1.address, 2)).to.be.equal(4); + }); + it('should fail on burning non existing token', async function () { + const {catalystAsBurner, user1} = await runCatalystSetup(); + await expect( + catalystAsBurner.burnFrom(user1.address, 1, 1) + ).to.be.revertedWith('ERC1155: burn amount exceeds totalSupply'); + }); + it('should fail on batch burning non existing tokens', async function () { + const {catalystAsBurner, user1} = await runCatalystSetup(); + const catalystId = [1, 2]; + const catalystAmount = [2, 2]; + await expect( + catalystAsBurner.burnBatchFrom( + user1.address, + catalystId, + catalystAmount + ) + ).to.be.revertedWith('ERC1155: burn amount exceeds totalSupply'); + }); + }); + describe('Metadata', function () { + it("user can view token's metadata", async function () { + const {catalyst} = await runCatalystSetup(); + for (let i = 0; i < catalystArray.length; i++) { + expect(await catalyst.uri(catalystArray[i])).to.be.equal( + `ipfs://${CATALYST_IPFS_CID_PER_TIER[i]}` + ); + } + }); + }); + + describe('Token transfer and approval', function () { + it('owner can approve operator', async function () { + const {catalyst, user1, catalystAsMinter, user2} = + await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 10); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(10); + await catalyst.connect(user1).setApprovalForAll(user2.address, true); + expect( + await catalyst.isApprovedForAll(user1.address, user2.address) + ).to.be.equal(true); + }); + it('approved operator can transfer', async function () { + const {catalyst, user1, catalystAsMinter, user2} = + await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 10); + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(10); + await catalyst + .connect(await ethers.provider.getSigner(user1.address)) + .setApprovalForAll(user2.address, true); + expect( + await catalyst.isApprovedForAll(user1.address, user2.address) + ).to.be.equal(true); + await catalyst + .connect(await ethers.provider.getSigner(user1.address)) + .safeTransferFrom(user1.address, user2.address, 1, 10, zeroAddress); + expect(await catalyst.balanceOf(user2.address, 1)).to.be.equal(10); + }); + it('approved operator can batch transfer', async function () { + const {catalyst, user1, catalystAsMinter, user2} = + await runCatalystSetup(); + await catalystAsMinter.mint(user1.address, 1, 10); + await catalystAsMinter.mint(user1.address, 2, 10); + + expect(await catalyst.balanceOf(user1.address, 1)).to.be.equal(10); + expect(await catalyst.balanceOf(user1.address, 2)).to.be.equal(10); + await catalyst + .connect(await ethers.provider.getSigner(user1.address)) + .setApprovalForAll(user2.address, true); + expect( + await catalyst.isApprovedForAll(user1.address, user2.address) + ).to.be.equal(true); + await catalyst + .connect(await ethers.provider.getSigner(user1.address)) + .safeBatchTransferFrom( + user1.address, + user2.address, + [1, 2], + [10, 10], + zeroAddress + ); + expect(await catalyst.balanceOf(user2.address, 1)).to.be.equal(10); + expect(await catalyst.balanceOf(user2.address, 2)).to.be.equal(10); + }); + it('should fail on transfering non existing token', async function () { + const {catalyst, user1, user2} = await runCatalystSetup(); + + await expect( + catalyst + .connect(user1) + .safeTransferFrom(user1.address, user2.address, 1, 1, '0x') + ).to.be.revertedWith('ERC1155: insufficient balance for transfer'); + }); + it('should fail on batch transfering non existing tokens', async function () { + const {catalyst, user1, user2} = await runCatalystSetup(); + const catalystId = [1, 2]; + const catalystAmount = [2, 2]; + await expect( + catalyst + .connect(user1) + .safeBatchTransferFrom( + user1.address, + user2.address, + catalystId, + catalystAmount, + '0x' + ) + ).to.be.revertedWith('ERC1155: insufficient balance for transfer'); + }); + }); + describe('OperatorFilterer', function () { + describe('common subscription setup', function () { + it('should be registered', async function () { + const {operatorFilterRegistry, Catalyst} = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isRegistered(Catalyst.address) + ).to.be.equal(true); + }); + + it('should set registry and subscribe to common subscription', async function () { + const { + operatorFilterRegistry, + TrustedForwarder, + operatorFilterSubscription, + catalystAdmin, + catalystMinter, + RoyaltyManagerContract, + } = await setupOperatorFilter(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + const catalyst = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + TrustedForwarder.address, + operatorFilterSubscription.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + await catalyst.deployed(); + await catalyst + .connect(catalystAdmin) + .setOperatorRegistry(operatorFilterRegistry.address); + expect(await catalyst.getOperatorFilterRegistry()).to.be.equals( + operatorFilterRegistry.address + ); + + await catalyst + .connect(catalystAdmin) + .registerAndSubscribe(operatorFilterSubscription.address, true); + + expect( + await operatorFilterRegistry.isRegistered(catalyst.address) + ).to.be.equals(true); + + expect( + await operatorFilterRegistry.subscriptionOf(catalyst.address) + ).to.be.equals(operatorFilterSubscription.address); + }); + + it('should revert when registry is set zero and subscription is set zero', async function () { + const { + TrustedForwarder, + operatorFilterSubscription, + catalystAdmin, + catalystMinter, + RoyaltyManagerContract, + } = await setupOperatorFilter(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + const catalyst = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + TrustedForwarder.address, + operatorFilterSubscription.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + await catalyst.deployed(); + await expect( + catalyst.connect(catalystAdmin).setOperatorRegistry(zeroAddress) + ).to.be.revertedWith('Catalyst: Zero address'); + + await expect( + catalyst + .connect(catalystAdmin) + .registerAndSubscribe(zeroAddress, true) + ).to.be.revertedWith('Catalyst: Zero address'); + }); + + it('should revert when registry is set and subscription is set by non-admin', async function () { + const { + TrustedForwarder, + operatorFilterSubscription, + catalystAdmin, + catalystMinter, + RoyaltyManagerContract, + user1, + defaultAdminRole, + operatorFilterRegistry, + } = await setupOperatorFilter(); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + const catalyst = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + TrustedForwarder.address, + operatorFilterSubscription.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + await catalyst.deployed(); + await expect( + catalyst + .connect(user1) + .setOperatorRegistry(operatorFilterRegistry.address) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${defaultAdminRole}` + ); + + await expect( + catalyst + .connect(user1) + .registerAndSubscribe(operatorFilterSubscription.address, true) + ).to.be.revertedWith( + `AccessControl: account ${user1.address.toLocaleLowerCase()} is missing role ${defaultAdminRole}` + ); + }); + + it('should be subscribed to common subscription', async function () { + const {operatorFilterRegistry, Catalyst, operatorFilterSubscription} = + await setupOperatorFilter(); + expect( + await operatorFilterRegistry.subscriptionOf(Catalyst.address) + ).to.be.equal(operatorFilterSubscription.address); + }); + + it('default subscription should blacklist Mock Market places 1, 2 and not 3, 4', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + DEFAULT_SUBSCRIPTION, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('common subscription should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + operatorFilterSubscription, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('Catalyst should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + Catalyst, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it("removing market places from common subscription's blacklist should reflect on Catalyst's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + Catalyst, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace1.address, + false + ); + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash, + false + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + }); + + it("adding market places to common subscription's blacklist should reflect on Catalyst's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace3, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + Catalyst, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace3.address, + true + ); + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash, + true + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + Catalyst.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + Catalyst.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + }); + }); + + describe('Catalyst transfer and approval ', function () { + it('should be able to safe transfer Catalyst if from is the owner of token', async function () { + const {Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Catalyst.safeTransferFrom( + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('should be able to safe batch transfer Catalyst if from is the owner of token', async function () { + const {Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Catalyst.safeBatchTransferFrom( + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Catalyst.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + + it('should be able to safe transfer Catalyst if from is the owner of Catalyst and to is a blacklisted marketplace', async function () { + const {mockMarketPlace1, Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Catalyst.safeTransferFrom( + users[0].address, + mockMarketPlace1.address, + 1, + 1, + '0x' + ); + + expect( + await Catalyst.balanceOf(mockMarketPlace1.address, 1) + ).to.be.equal(1); + }); + + it('should be able to safe batch transfer Catalysts if from is the owner of Catalysts and to is a blacklisted marketplace', async function () { + const {mockMarketPlace1, Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Catalyst.safeBatchTransferFrom( + users[0].address, + mockMarketPlace1.address, + [1, 2], + [1, 1], + '0x' + ); + + expect( + await Catalyst.balanceOf(mockMarketPlace1.address, 1) + ).to.be.equal(1); + expect( + await Catalyst.balanceOf(mockMarketPlace1.address, 2) + ).to.be.equal(1); + }); + + it('it should not setApprovalForAll blacklisted market places', async function () { + const {mockMarketPlace1, users} = await setupOperatorFilter(); + await expect( + users[0].Catalyst.setApprovalForAll(mockMarketPlace1.address, true) + ).to.be.reverted; + }); + + it('it should setApprovalForAll non blacklisted market places', async function () { + const {mockMarketPlace3, Catalyst, users} = await setupOperatorFilter(); + await users[0].Catalyst.setApprovalForAll( + mockMarketPlace3.address, + true + ); + expect( + await Catalyst.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + }); + + it('it should not be able to setApprovalForAll trusted forwarder if black listed', async function () { + const { + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + users, + TrustedForwarder, + } = await setupOperatorFilter(); + + const TrustedForwarderCodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + TrustedForwarder.address + ); + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + TrustedForwarderCodeHash, + true + ); + + await expect( + users[1].Catalyst.setApprovalForAll(TrustedForwarder.address, true) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to setApprovalForAll non blacklisted market places after they are blacklisted ', async function () { + const { + mockMarketPlace3, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + Catalyst, + users, + } = await setupOperatorFilter(); + await users[0].Catalyst.setApprovalForAll( + mockMarketPlace3.address, + true + ); + + expect( + await Catalyst.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + users[1].Catalyst.setApprovalForAll(mockMarketPlace3.address, true) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to setApprovalForAll non blacklisted market places after there codeHashes are blacklisted ', async function () { + const { + mockMarketPlace3, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + Catalyst, + users, + } = await setupOperatorFilter(); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + mockMarketPlace3.address + ); + + await users[0].Catalyst.setApprovalForAll( + mockMarketPlace3.address, + true + ); + + expect( + await Catalyst.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + users[1].Catalyst.setApprovalForAll(mockMarketPlace3.address, true) + ).to.be.revertedWith; + }); + + it('it should be able to setApprovalForAll blacklisted market places after they are removed from the blacklist ', async function () { + const { + mockMarketPlace1, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + Catalyst, + users, + } = await setupOperatorFilter(); + + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + mockMarketPlace1.address + ); + + await expect( + users[0].Catalyst.setApprovalForAll(mockMarketPlace1.address, true) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace1.address, + false + ); + + await users[0].Catalyst.setApprovalForAll( + mockMarketPlace1.address, + true + ); + + expect( + await Catalyst.isApprovedForAll( + users[0].address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + }); + + it('it should not be able to transfer through blacklisted market places', async function () { + const {mockMarketPlace1, Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + await expect( + mockMarketPlace1.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to transfer through market places after they are blacklisted', async function () { + const { + mockMarketPlace3, + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + } = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + + await mockMarketPlace3.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + mockMarketPlace3.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to transfer through trusted forwarder after it is blacklisted', async function () { + const { + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + TrustedForwarder, + } = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 2); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + TrustedForwarder.address, + true + ); + + const data = await Catalyst.connect( + users[0].Catalyst.signer + ).populateTransaction[ + 'safeTransferFrom(address,address,uint256,uint256,bytes)' + ](users[0].address, users[1].address, 1, 1, '0x'); + + await TrustedForwarder.execute({...data, value: BigNumber.from(0)}); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to transfer through trusted forwarder after if sender is blacklisted', async function () { + const {Catalyst, users, TrustedForwarder, mockMarketPlace1} = + await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + const data = await Catalyst.connect( + ethers.provider.getSigner(mockMarketPlace1.address) + ).populateTransaction[ + 'safeTransferFrom(address,address,uint256,uint256,bytes)' + ](users[0].address, users[1].address, 1, 1, '0x'); + + await expect( + TrustedForwarder.execute({...data, value: BigNumber.from(0)}) + ).to.be.revertedWith('Call execution failed'); + }); + + it('it should be able to transfer through non blacklisted market places', async function () { + const {mockMarketPlace3, Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to transfer through non blacklisted market places after their codeHash is blacklisted', async function () { + const { + mockMarketPlace3, + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + } = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + mockMarketPlace3.address + ); + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + mockMarketPlace3.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to transfer through blacklisted market places after they are removed from blacklist', async function () { + const { + mockMarketPlace1, + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + } = await setupOperatorFilter(); + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + mockMarketPlace1.address + ); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + await expect( + mockMarketPlace1.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace1.address, + false + ); + await mockMarketPlace1.transferTokenForERC1155( + Catalyst.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to batch transfer through blacklisted market places', async function () { + const {mockMarketPlace1, Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + await expect( + mockMarketPlace1.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to batch transfer through market places after they are blacklisted', async function () { + const { + mockMarketPlace3, + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + } = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 2); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 2); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + + await mockMarketPlace3.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + + expect(await Catalyst.balanceOf(users[1].address, 2)).to.be.equal(1); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + mockMarketPlace3.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to batch transfer through non blacklisted market places', async function () { + const {mockMarketPlace3, Catalyst, users} = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Catalyst.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + + it('it should not be able to batch transfer through non blacklisted market places after their codeHash is blacklisted', async function () { + const { + mockMarketPlace3, + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + } = await setupOperatorFilter(); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 2); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 2); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Catalyst.balanceOf(users[1].address, 2)).to.be.equal(1); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + mockMarketPlace3.address + ); + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + mockMarketPlace3.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to batch transfer through blacklisted market places after they are removed from blacklist', async function () { + const { + mockMarketPlace1, + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + } = await setupOperatorFilter(); + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + mockMarketPlace1.address + ); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + await expect( + mockMarketPlace1.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace1.address, + false + ); + await mockMarketPlace1.batchTransferTokenERC1155( + Catalyst.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Catalyst.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + + it('should be able to batch transfer through trusted forwarder if it is black listed', async function () { + const { + Catalyst, + users, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + TrustedForwarder, + } = await setupOperatorFilter(); + const TrustedForwarderCodeHash = + await operatorFilterRegistryAsOwner.codeHashOf( + TrustedForwarder.address + ); + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 1); + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + TrustedForwarderCodeHash, + true + ); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + TrustedForwarder.address, + true + ); + + const data = await Catalyst.connect( + users[0].Catalyst.signer + ).populateTransaction[ + 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)' + ](users[0].address, users[1].address, [1, 2], [1, 1], '0x'); + + await TrustedForwarder.execute({...data, value: BigNumber.from(0)}); + expect(await Catalyst.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await Catalyst.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + it('should not be able to batch transfer through trusted forwarder if the sender is black listed', async function () { + const {Catalyst, users, TrustedForwarder, mockMarketPlace1} = + await setupOperatorFilter(); + + await Catalyst.mintWithoutMinterRole(users[0].address, 1, 1); + await Catalyst.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].Catalyst.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + const data = await Catalyst.connect( + ethers.provider.getSigner(mockMarketPlace1.address) + ).populateTransaction[ + 'safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)' + ](users[0].address, users[1].address, [1, 2], [1, 1], '0x'); + + await expect( + TrustedForwarder.execute({...data, value: BigNumber.from(0)}) + ).to.be.revertedWith('Call execution failed'); + }); + }); + }); +}); diff --git a/packages/asset/test/CatalystRoyalty.test.ts b/packages/asset/test/CatalystRoyalty.test.ts new file mode 100644 index 0000000000..27268a2ea2 --- /dev/null +++ b/packages/asset/test/CatalystRoyalty.test.ts @@ -0,0 +1,159 @@ +import {ethers} from 'hardhat'; +import {expect} from 'chai'; +import {BigNumber} from 'ethers'; +import {catalystRoyaltyDistribution} from './fixtures/catalyst/catalystRoyaltyFixture'; +describe('catalyst royalty', function () { + it('manager contract royalty setter can set Eip 2981 royaltyBps for other contracts (catalyst)', async function () { + const {managerAsRoyaltySetter, catalystAsMinter} = + await catalystRoyaltyDistribution(); + expect( + await managerAsRoyaltySetter.contractRoyalty(catalystAsMinter.address) + ).to.be.equal(0); + await managerAsRoyaltySetter.setContractRoyalty( + catalystAsMinter.address, + 500 + ); + expect( + await managerAsRoyaltySetter.contractRoyalty(catalystAsMinter.address) + ).to.be.equal(500); + }); + + it('only manager contract royalty setter can set Eip 2981 royaltyBps for other contracts (catalyst)', async function () { + const {manager, seller, catalystAsMinter, contractRoyaltySetterRole} = + await catalystRoyaltyDistribution(); + await expect( + manager.connect(seller).setContractRoyalty(catalystAsMinter.address, 500) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLocaleLowerCase()} is missing role ${contractRoyaltySetterRole}` + ); + }); + it('catalyst should return EIP2981 royalty recipient and royalty for other contracts(catalyst)', async function () { + const {commonRoyaltyReceiver, catalystAsMinter, managerAsRoyaltySetter} = + await catalystRoyaltyDistribution(); + await managerAsRoyaltySetter.setContractRoyalty( + catalystAsMinter.address, + 500 + ); + const id = 1; + const priceToken = 300000; + const royaltyInfo = await catalystAsMinter.royaltyInfo(id, priceToken); + expect(royaltyInfo[0]).to.be.equals(commonRoyaltyReceiver.address); + expect(royaltyInfo[1]).to.be.equals((500 * priceToken) / 10000); + }); + + it('catalyst should same return EIP2981 royalty recipient for different tokens contracts(catalyst)', async function () { + const {commonRoyaltyReceiver, catalystAsMinter, managerAsRoyaltySetter} = + await catalystRoyaltyDistribution(); + await managerAsRoyaltySetter.setContractRoyalty( + catalystAsMinter.address, + 500 + ); + const id = 1; + const id2 = 2; + const priceToken = 300000; + const royaltyInfo = await catalystAsMinter.royaltyInfo(id, priceToken); + expect(royaltyInfo[0]).to.be.equals(commonRoyaltyReceiver.address); + expect(royaltyInfo[1]).to.be.equals((500 * priceToken) / 10000); + + const royaltyInfo2 = await catalystAsMinter.royaltyInfo(id2, priceToken); + expect(royaltyInfo2[0]).to.be.equals(commonRoyaltyReceiver.address); + expect(royaltyInfo2[1]).to.be.equals((500 * priceToken) / 10000); + }); + + it('should split ERC20 using EIP2981', async function () { + const { + catalystAsMinter, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + managerAsRoyaltySetter, + } = await catalystRoyaltyDistribution(); + await catalystAsMinter.mint(seller.address, 1, 1); + + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await catalystAsMinter + .connect(seller) + .setApprovalForAll(mockMarketplace.address, true); + expect(await catalystAsMinter.balanceOf(seller.address, 1)).to.be.equals(1); + expect(await ERC20.balanceOf(commonRoyaltyReceiver.address)).to.be.equals( + 0 + ); + + await managerAsRoyaltySetter.setContractRoyalty( + catalystAsMinter.address, + 500 + ); + + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + catalystAsMinter.address, + 1, + buyer.address, + seller.address, + true + ); + + expect(await ERC20.balanceOf(commonRoyaltyReceiver.address)).to.be.equals( + (1000000 / 10000) * 500 + ); + }); + + it('should split ETH using EIP2981', async function () { + const { + catalystAsMinter, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + managerAsRoyaltySetter, + user, + } = await catalystRoyaltyDistribution(); + await catalystAsMinter.mint(seller.address, 1, 1); + + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await catalystAsMinter + .connect(seller) + .setApprovalForAll(mockMarketplace.address, true); + expect(await catalystAsMinter.balanceOf(seller.address, 1)).to.be.equals(1); + const value = ethers.utils.parseUnits('1000', 'ether'); + + await managerAsRoyaltySetter.setContractRoyalty( + catalystAsMinter.address, + 500 + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + await mockMarketplace + .connect(user) + .distributeRoyaltyEIP2981( + 0, + ERC20.address, + catalystAsMinter.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ).to.be.equal(value.mul(BigNumber.from(500)).div(BigNumber.from(10000))); + }); +}); diff --git a/packages/asset/test/Splitter.abi.ts b/packages/asset/test/Splitter.abi.ts new file mode 100644 index 0000000000..3d0d752164 --- /dev/null +++ b/packages/asset/test/Splitter.abi.ts @@ -0,0 +1,280 @@ +export const splitterAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'erc20Contract', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ERC20Transferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ETHTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'recipientAddress', + type: 'address', + }, + ], + name: 'RecipientSet', + type: 'event', + }, + { + inputs: [], + name: 'getRecipients', + outputs: [ + { + components: [ + { + internalType: 'address payable', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint16', + name: 'bps', + type: 'uint16', + }, + ], + internalType: 'struct Recipient[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address payable', + name: '_recipient', + type: 'address', + }, + { + internalType: 'address', + name: '_royaltyManager', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'forwarder', + type: 'address', + }, + ], + name: 'isTrustedForwarder', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'recipient', + outputs: [ + { + internalType: 'address payable', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'royaltyManager', + outputs: [ + { + internalType: 'contract IRoyaltyManager', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address payable', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint16', + name: 'bps', + type: 'uint16', + }, + ], + internalType: 'struct Recipient[]', + name: 'recipients', + type: 'tuple[]', + }, + ], + name: 'setRecipients', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'erc20Contract', + type: 'address', + }, + ], + name: 'splitERC20Tokens', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'splitETH', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes4', + name: 'interfaceId', + type: 'bytes4', + }, + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + stateMutability: 'payable', + type: 'receive', + }, +]; diff --git a/packages/asset/test/TokenUtils.test.ts b/packages/asset/test/TokenUtils.test.ts new file mode 100644 index 0000000000..498cb1805d --- /dev/null +++ b/packages/asset/test/TokenUtils.test.ts @@ -0,0 +1,178 @@ +import {expect} from 'chai'; +import {runTokenIdUtilsSetup} from './fixtures/tokenIdUtilsFixture'; +import {ethers} from 'hardhat'; + +describe('TokenIdUtils (/packages/asset/contracts/libraries/TokenIdUtils.ts)', function () { + it('should generate a token id', async function () { + const {generateTokenId} = await runTokenIdUtilsSetup(); + const tokenId = await generateTokenId(); + expect(tokenId).to.not.be.undefined; + expect(tokenId.toHexString()).to.have.lengthOf(46); + }); + describe("Creator's address", function () { + it('should generate a token id with correct creator - manual extraction', async function () { + const {generateTokenId, address} = await runTokenIdUtilsSetup(); + const tokenId = await generateTokenId(); + const creatorAddressBigNumber = tokenId.and( + ethers.constants.MaxUint256.shr(96) // Create a mask for the last 160 bits + ); + const creatorAddressPaddedHex = creatorAddressBigNumber.toHexString(); + const creatorAddressHex = creatorAddressPaddedHex; + const creator = ethers.utils.getAddress(creatorAddressHex); + expect(creator).equal(address); + }); + it('should generate a token id with correct creator - using getter function', async function () { + const {tokenIdUtils, generateTokenId, address} = + await runTokenIdUtilsSetup(); + const tokenId = await generateTokenId(); + const tokenIdAddress = await tokenIdUtils.getCreatorAddress(tokenId); + expect(tokenIdAddress).equal(address); + }); + }); + describe('Tier', function () { + it('should generate a token id with correct tier - using getter function', async function () { + const {tokenIdUtils, generateTokenId} = await runTokenIdUtilsSetup(); + const tier = 6; + const tokenId = await generateTokenId(undefined, tier); + const returnedTier = await tokenIdUtils.getTier(tokenId); + expect(returnedTier).equal(tier); + }); + it('should generate a token id with correct tier - manual extraction', async function () { + const {generateTokenId, TIER_SHIFT, TIER_MASK} = + await runTokenIdUtilsSetup(); + const tier = 6; + const tokenId = await generateTokenId(undefined, tier); + const returnedTier = tokenId.shr(TIER_SHIFT).and(TIER_MASK).toNumber(); + expect(returnedTier).equal(tier); + }); + }); + describe('Creator nonce', function () { + it('should generate a token id with correct creator nonce - using getter function', async function () { + const {tokenIdUtils, generateTokenId} = await runTokenIdUtilsSetup(); + const creatorNonce = 120; + const tokenId = await generateTokenId(undefined, undefined, creatorNonce); + const returnedNonce = await tokenIdUtils.getCreatorNonce(tokenId); + expect(returnedNonce).equal(creatorNonce); + }); + + it('should generate a token id with correct creator nonce - manual extraction', async function () { + const {generateTokenId, NONCE_SHIFT, NONCE_MASK} = + await runTokenIdUtilsSetup(); + const creatorNonce = 120; + const tokenId = await generateTokenId(undefined, undefined, creatorNonce); + const returnedNonce = tokenId.shr(NONCE_SHIFT).and(NONCE_MASK).toNumber(); + expect(returnedNonce).equal(creatorNonce); + }); + }); + describe('Reveal nonce', function () { + it('should generate a token id with correct reveal nonce - using getter function', async function () { + const {tokenIdUtils, generateTokenId} = await runTokenIdUtilsSetup(); + const revealNonce = 777; + const tokenId = await generateTokenId( + undefined, + undefined, + undefined, + revealNonce + ); + const returnedRevealNonce = await tokenIdUtils.getRevealNonce(tokenId); + expect(returnedRevealNonce).equal(revealNonce); + }); + + it('should generate a token id with correct reveal nonce - manual extraction', async function () { + const {generateTokenId, REVEAL_NONCE_SHIFT, REVEAL_NONCE_MASK} = + await runTokenIdUtilsSetup(); + const revealNonce = 777; + const tokenId = await generateTokenId( + undefined, + undefined, + undefined, + revealNonce + ); + const returnedRevealNonce = tokenId + .shr(REVEAL_NONCE_SHIFT) + .and(REVEAL_NONCE_MASK) + .toNumber(); + expect(returnedRevealNonce).equal(revealNonce); + }); + it('should return true if reveal nonce is non-zero', async function () { + const {tokenIdUtils, generateTokenId} = await runTokenIdUtilsSetup(); + const revealNonce = 777; + const tokenId = await generateTokenId( + undefined, + undefined, + undefined, + revealNonce + ); + const returnedRevealNonce = await tokenIdUtils.isRevealed(tokenId); + expect(returnedRevealNonce).equal(true); + }); + it('should return false if reveal nonce is zero', async function () { + const {tokenIdUtils, generateTokenId} = await runTokenIdUtilsSetup(); + const revealNonce = 0; + const tokenId = await generateTokenId( + undefined, + undefined, + undefined, + revealNonce + ); + const returnedRevealNonce = await tokenIdUtils.isRevealed(tokenId); + expect(returnedRevealNonce).equal(false); + }); + }); + + describe('Bridged flag', function () { + it('should generate a token id with correct bridged flag - using getter function', async function () { + const {tokenIdUtils, generateTokenId} = await runTokenIdUtilsSetup(); + const bridged = true; + const tokenId = await generateTokenId( + undefined, + undefined, + undefined, + undefined, + bridged + ); + const returnedBridged = await tokenIdUtils.isBridged(tokenId); + expect(returnedBridged).equal(bridged); + }); + + it('should generate a token id with correct bridged flag - manual extraction', async function () { + const {generateTokenId, BRIDGED_SHIFT, BRIDGED_MASK} = + await runTokenIdUtilsSetup(); + const bridged = true; + const tokenId = await generateTokenId( + undefined, + undefined, + undefined, + undefined, + bridged + ); + const returnedBridged = + tokenId.shr(BRIDGED_SHIFT).and(BRIDGED_MASK).toNumber() === 1; + expect(returnedBridged).equal(bridged); + }); + }); + describe('Asset Data', function () { + it('should return correct asset data', async function () { + const {tokenIdUtils, generateTokenId, address} = + await runTokenIdUtilsSetup(); + const creator = address; + const tier = 6; + const creatorNonce = 120; + const revealNonce = 777; + const bridged = true; + const tokenId = await generateTokenId( + creator, + tier, + creatorNonce, + revealNonce, + bridged + ); + const returnedAssetData = await tokenIdUtils.getData(tokenId); + expect(ethers.utils.getAddress(returnedAssetData.creator)).equal(creator); + expect(returnedAssetData.tier).equal(tier); + expect(returnedAssetData.creatorNonce).equal(creatorNonce); + expect(returnedAssetData.revealed).equal(true); + expect(returnedAssetData.bridged).equal(bridged); + }); + }); +}); diff --git a/packages/asset/test/fixtures/asset/assetCreateFixtures.ts b/packages/asset/test/fixtures/asset/assetCreateFixtures.ts new file mode 100644 index 0000000000..a26123f61c --- /dev/null +++ b/packages/asset/test/fixtures/asset/assetCreateFixtures.ts @@ -0,0 +1,338 @@ +import {ethers, upgrades} from 'hardhat'; +import { + createAssetMintSignature, + createMultipleAssetsMintSignature, +} from '../../utils/createSignature'; +import { + DEFAULT_SUBSCRIPTION, + CATALYST_BASE_URI, + CATALYST_IPFS_CID_PER_TIER, +} from '../../../data/constants'; + +const name = 'Sandbox Asset Create'; +const version = '1.0'; + +export async function runCreateTestSetup() { + const [ + catalystMinter, + trustedForwarder, + assetAdmin, + user, + otherWallet, + catalystAdmin, + authValidatorAdmin, + backendAuthWallet, + commonRoyaltyReceiver, + managerAdmin, + contractRoyaltySetter, + mockMarketplace1, + mockMarketplace2, + ] = await ethers.getSigners(); + + // test upgradeable contract using '@openzeppelin/hardhat-upgrades' + // DEPLOY DEPENDENCIES: ASSET, CATALYST, AUTH VALIDATOR, OPERATOR FILTER REGISTRANT, ROYALTIES + + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketplace1.address, mockMarketplace2.address] + ); + + // Operator Filter Registrant + const OperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + + // Provide: address _owner, address _localRegistry + const OperatorFilterSubscriptionContract = + await OperatorFilterSubscriptionFactory.deploy( + assetAdmin.address, + operatorFilterRegistry.address + ); + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + trustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const AssetFactory = await ethers.getContractFactory('Asset'); + const AssetContract = await upgrades.deployProxy( + AssetFactory, + [ + trustedForwarder.address, + assetAdmin.address, + 'ipfs://', + OperatorFilterSubscriptionContract.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await AssetContract.deployed(); + const RoyaltyManagerAsAdmin = RoyaltyManagerContract.connect(managerAdmin); + const splitterDeployerRole = + await RoyaltyManagerContract.SPLITTER_DEPLOYER_ROLE(); + await RoyaltyManagerAsAdmin.grantRole( + splitterDeployerRole, + AssetContract.address + ); + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + const CatalystContract = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await CatalystContract.deployed(); + + const AuthValidatorFactory = await ethers.getContractFactory( + 'AuthSuperValidator' + ); + const AuthValidatorContract = await AuthValidatorFactory.deploy( + authValidatorAdmin.address + ); + + await AuthValidatorContract.deployed(); + + // END DEPLOY DEPENDENCIES + + const MockAssetCreate = await ethers.getContractFactory('MockAssetCreate'); + const MockAssetCreateContract = await MockAssetCreate.deploy(); + await MockAssetCreateContract.deployed(); + + const AssetCreateFactory = await ethers.getContractFactory('AssetCreate'); + + const AssetCreateContract = await upgrades.deployProxy( + AssetCreateFactory, + [ + name, + version, + AssetContract.address, + CatalystContract.address, + AuthValidatorContract.address, + trustedForwarder.address, + assetAdmin.address, // DEFAULT_ADMIN_ROLE + ], + { + initializer: 'initialize', + } + ); + + await AssetCreateContract.deployed(); + + const AssetCreateContractAsUser = AssetCreateContract.connect(user); + + // SETUP VALIDATOR + await AuthValidatorContract.connect(authValidatorAdmin).setSigner( + AssetCreateContract.address, + backendAuthWallet.address + ); + + // SETUP ROLES + // get AssetContract as DEFAULT_ADMIN_ROLE + const AssetAsAdmin = AssetContract.connect(assetAdmin); + const MinterRole = await AssetAsAdmin.MINTER_ROLE(); + await AssetAsAdmin.grantRole(MinterRole, AssetCreateContract.address); + + // get CatalystContract as DEFAULT_ADMIN_ROLE + const CatalystAsAdmin = CatalystContract.connect(catalystAdmin); + const CatalystBurnerRole = await CatalystAsAdmin.BURNER_ROLE(); + await CatalystAsAdmin.grantRole( + CatalystBurnerRole, + AssetCreateContract.address + ); + + const AdminRole = await AssetCreateContract.DEFAULT_ADMIN_ROLE(); + + const AssetCreateContractAsAdmin = AssetCreateContract.connect(assetAdmin); + const SpecialMinterRole = await AssetCreateContract.SPECIAL_MINTER_ROLE(); + + const PauserRole = await AssetCreateContract.PAUSER_ROLE(); + await AssetCreateContractAsAdmin.grantRole(PauserRole, assetAdmin.address); + // END SETUP ROLES + + // HELPER FUNCTIONS + const grantSpecialMinterRole = async (address: string) => { + await AssetCreateContractAsAdmin.grantRole(SpecialMinterRole, address); + }; + + const mintCatalyst = async ( + tier: number, + amount: number, + to = user.address + ) => { + const signer = catalystMinter; + await CatalystContract.connect(signer).mint(to, tier, amount); + }; + + const mintSingleAsset = async ( + signature: string, + tier: number, + amount: number, + revealed: boolean, + metadataHash: string + ) => { + const tx = await AssetCreateContractAsUser.createAsset( + signature, + tier, + amount, + revealed, + metadataHash, + user.address + ); + const result = await tx.wait(); + return result; + }; + + const mintMultipleAssets = async ( + signature: string, + tiers: number[], + amounts: number[], + revealed: boolean[], + metadataHashes: string[] + ) => { + const tx = await AssetCreateContractAsUser.createMultipleAssets( + signature, + tiers, + amounts, + revealed, + metadataHashes, + user.address + ); + + const result = await tx.wait(); + return result; + }; + + const mintSpecialAsset = async ( + signature: string, + amount: number, + metadataHash: string + ) => { + const tx = await AssetCreateContractAsUser.createSpecialAsset( + signature, + amount, + metadataHash, + user.address + ); + const result = await tx.wait(); + return result; + }; + + const getCreatorNonce = async (creator: string) => { + const nonce = await AssetCreateContract.creatorNonces(creator); + return nonce; + }; + + const generateSingleMintSignature = async ( + creator: string, + tier: number, + amount: number, + revealed: boolean, + metadataHash: string + ) => { + const signature = await createAssetMintSignature( + creator, + tier, + amount, + revealed, + metadataHash, + AssetCreateContract, + backendAuthWallet + ); + return signature; + }; + + const generateMultipleMintSignature = async ( + creator: string, + tiers: number[], + amounts: number[], + revealed: boolean[], + metadataHashes: string[] + ) => { + const signature = await createMultipleAssetsMintSignature( + creator, + tiers, + amounts, + revealed, + metadataHashes, + AssetCreateContract, + backendAuthWallet + ); + return signature; + }; + + const pause = async () => { + await AssetCreateContractAsAdmin.pause(); + }; + + const unpause = async () => { + await AssetCreateContractAsAdmin.unpause(); + }; + + // END HELPER FUNCTIONS + + return { + metadataHashes: [ + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJA', + 'QmcU8NLdWyoDAbPc67irYpCnCH9ciRUjMC784dvRfy1Fja', + ], + additionalMetadataHash: 'QmZEhV6rMsZfNyAmNKrWuN965xaidZ8r5nd2XkZq9yZ95L', + user, + AdminRole, + PauserRole, + trustedForwarder, + otherWallet, + AssetContract, + AssetCreateContract, + AssetCreateContractAsUser, + AssetCreateContractAsAdmin, + AuthValidatorContract, + CatalystContract, + MockAssetCreateContract, + mintCatalyst, + mintSingleAsset, + mintMultipleAssets, + mintSpecialAsset, + grantSpecialMinterRole, + generateSingleMintSignature, + generateMultipleMintSignature, + getCreatorNonce, + pause, + unpause, + }; +} diff --git a/packages/asset/test/fixtures/asset/assetFixture.ts b/packages/asset/test/fixtures/asset/assetFixture.ts new file mode 100644 index 0000000000..7ecff10e3a --- /dev/null +++ b/packages/asset/test/fixtures/asset/assetFixture.ts @@ -0,0 +1,294 @@ +import {ethers, upgrades} from 'hardhat'; +import {DEFAULT_SUBSCRIPTION} from '../../../data/constants'; + +export function generateOldAssetId( + creator: string, + assetNumber: number, + isNFT: boolean +) { + const hex = assetNumber.toString(16); + const hexLength = hex.length; + let zeroAppends = ''; + const zeroAppendsLength = 24 - hexLength; + for (let i = 0; i < zeroAppendsLength; i++) { + if (i == zeroAppendsLength - 1) { + if (isNFT) { + zeroAppends = '8' + zeroAppends; + } else { + zeroAppends = zeroAppends + '0'; + } + } else { + zeroAppends = zeroAppends + '0'; + } + } + return `${creator}${zeroAppends}${hex}`; +} + +export function generateAssetId( + creator: string, + tier: number, + nonce: number, + revealNonce: number, + Bridged: boolean +) { + const tierHex = tier.toString(16); + const tierHexLength = tierHex.length; + let tierAppend; + if (tierHexLength >= 2) { + tierAppend = tierHex.substring(tierHexLength - 2); + } else { + tierAppend = '0' + tierHex; + } + + let nonceHex = nonce.toString(16); + const nonceLength = nonceHex.length; + 1; + let nonceAppend; + if (nonceLength >= 4) { + nonceAppend = nonceHex.substring(nonceLength - 4); + } else { + for (let i = nonceLength; i < 4; i++) { + nonceHex = '0' + nonceHex; + } + nonceAppend = nonceHex; + } + + let revealNonceHex = revealNonce.toString(16); + const revealNonceHexLength = revealNonceHex.length; + let revealNonceAppend; + if (revealNonceHexLength >= 4) { + revealNonceAppend = revealNonceHex.substring(revealNonceHexLength - 4); + } else { + for (let i = revealNonceHexLength; i < 4; i++) { + revealNonceHex = '0' + revealNonceHex; + } + revealNonceAppend = revealNonceHex; + } + + const zeroAppends = '0x00000000000000'; + + return `${zeroAppends}${ + Bridged ? '1' : '0' + }${revealNonceAppend}${nonceAppend}${tierAppend}${creator.substring(2)}`; +} + +export async function runAssetSetup() { + const [ + assetAdmin, + owner, + secondOwner, + bridgeMinter, + minter, + burner, + trustedForwarder, + mockMarketplace1, + mockMarketplace2, + commonRoyaltyReceiver, + managerAdmin, + contractRoyaltySetter, + ] = await ethers.getSigners(); + + // test upgradeable contract using '@openzeppelin/hardhat-upgrades' + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + trustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const AssetFactory = await ethers.getContractFactory('Asset'); + + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketplace1.address, mockMarketplace2.address] + ); + + // Operator Filter Registrant + const OperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + + // Provide: address _owner, address _localRegistry + const OperatorFilterSubscriptionContract = + await OperatorFilterSubscriptionFactory.deploy( + assetAdmin.address, + operatorFilterRegistry.address + ); + + const AssetContract = await upgrades.deployProxy( + AssetFactory, + [ + trustedForwarder.address, + assetAdmin.address, + 'ipfs://', + OperatorFilterSubscriptionContract.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await AssetContract.deployed(); + const RoyaltyManagerAsAdmin = RoyaltyManagerContract.connect(managerAdmin); + const splitterDeployerRole = + await RoyaltyManagerContract.SPLITTER_DEPLOYER_ROLE(); + await RoyaltyManagerAsAdmin.grantRole( + splitterDeployerRole, + AssetContract.address + ); + + const generateRandomTokenId = () => { + return ethers.utils.randomBytes(32); + }; + + // Asset contract is not user-facing and we block users from minting directly + // Contracts that interact with Asset must have the necessary ROLE + // Here we set up the necessary roles for testing + const AssetContractAsAdmin = AssetContract.connect(assetAdmin); + const AssetContractAsMinter = AssetContract.connect(minter); + const AssetContractAsBurner = AssetContract.connect(burner); + const AssetContractAsOwner = AssetContract.connect(owner); + const defaultAdminRole = await AssetContract.DEFAULT_ADMIN_ROLE(); + const minterRole = await AssetContract.MINTER_ROLE(); + const burnerRole = await AssetContract.BURNER_ROLE(); + await AssetContractAsAdmin.grantRole(minterRole, minter.address); + await AssetContractAsAdmin.grantRole(burnerRole, burner.address); + // end set up roles + + const MockAsset = await ethers.getContractFactory('MockAsset'); + const MockAssetContract = await MockAsset.deploy(); + await MockAssetContract.deployed(); + + const metadataHashes = [ + 'QmSRVTH8VumE42fqmdzPHuA57LjCaUXQRequVzEDTGMyHY', + 'QmTeRr1J2kaKM6e1m8ixLfZ31hcb7XNktpbkWY5tMpjiFR', + 'QmUxnKe5DyjxKuwq2AMGDLYeQALnQxcffCZCgtj5a41DYw', + 'QmYQztw9x8WyrUFDxuc5D4xYaN3pBXWNGNAaguvfDhLLgg', + 'QmUXH1JBPMYxCmzNEMRDGTPtHmePvbo4uVEBreN3sowDwG', + 'QmdRwSPCuPGfxSYTaot9Eqz8eU9w1DGp8mY97pTCjnSWqk', + 'QmNrwUiZfQLYaZFHNLzxqfiLxikKYRzZcdWviyDaNhrVhm', + ]; + const baseURI = 'ipfs://'; + + const mintOne = async ( + recipient = minter.address, + tokenId = generateRandomTokenId(), + amount = 10, + metadataHash = metadataHashes[0] + ) => { + const tx = await AssetContractAsMinter.mint( + recipient, + tokenId, + amount, + metadataHash + ); + await tx.wait(); + return { + tx, + tokenId, + metadataHash, + }; + }; + + const burnOne = async ( + account: string, + tokenId: Uint8Array, + amount: number + ) => { + const tx = await AssetContractAsBurner.burnFrom(account, tokenId, amount); + await tx.wait(); + return { + tx, + tokenId, + }; + }; + + const mintBatch = async ( + recipient = minter.address, + tokenIds = [generateRandomTokenId(), generateRandomTokenId()], + amounts = [10, 5], + metadata = [metadataHashes[0], metadataHashes[1]] + ) => { + const tx = await AssetContractAsMinter.mintBatch( + recipient, + tokenIds, + amounts, + metadata + ); + await tx.wait(); + + return { + tx, + tokenIds, + metadataHashes, + }; + }; + + const burnBatch = async ( + account: string, + tokenIds: Uint8Array[], + amounts: number[] + ) => { + const tx = await AssetContractAsBurner.burnBatchFrom( + account, + tokenIds, + amounts + ); + await tx.wait(); + + return { + tx, + tokenIds, + }; + }; + + return { + MockAssetContract, + AssetContract, + AssetContractAsOwner, + AssetContractAsMinter, + AssetContractAsBurner, + AssetContractAsAdmin, + owner, + assetAdmin, + minter, + burner, + trustedForwarder, + secondOwner, + bridgeMinter, + minterRole, + burnerRole, + defaultAdminRole, + metadataHashes, + baseURI, + generateRandomTokenId, + mintOne, + burnOne, + burnBatch, + mintBatch, + generateAssetId, + }; +} diff --git a/packages/asset/test/fixtures/asset/assetRevealFixtures.ts b/packages/asset/test/fixtures/asset/assetRevealFixtures.ts new file mode 100644 index 0000000000..dd62ce92bf --- /dev/null +++ b/packages/asset/test/fixtures/asset/assetRevealFixtures.ts @@ -0,0 +1,392 @@ +import {ethers, upgrades} from 'hardhat'; +import {Event} from 'ethers'; +import { + batchRevealSignature, + burnAndRevealSignature, + revealSignature, +} from '../../utils/revealSignature'; +import { + DEFAULT_SUBSCRIPTION, + CATALYST_BASE_URI, + CATALYST_IPFS_CID_PER_TIER, +} from '../../../data/constants'; + +const name = 'Sandbox Asset Reveal'; +const version = '1.0'; + +export async function runRevealTestSetup() { + const [ + catalystMinter, + trustedForwarder, + assetAdmin, + user, + catalystAdmin, + authValidatorAdmin, + backendAuthWallet, + mockMarketplace1, + mockMarketplace2, + commonRoyaltyReceiver, + managerAdmin, + contractRoyaltySetter, + ] = await ethers.getSigners(); + + // test upgradeable contract using '@openzeppelin/hardhat-upgrades' + // DEPLOY DEPENDENCIES: ASSET, CATALYST, AUTH VALIDATOR, OPERATOR FILTER + // note: reveal tests use a MockMinter instead of AssetCreate + + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketplace1.address, mockMarketplace2.address] + ); + + // Operator Filter Registrant + const OperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + + // Provide: address _owner, address _localRegistry + const OperatorFilterSubscriptionContract = + await OperatorFilterSubscriptionFactory.deploy( + assetAdmin.address, + operatorFilterRegistry.address + ); + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + trustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const AssetFactory = await ethers.getContractFactory('Asset'); + const AssetContract = await upgrades.deployProxy( + AssetFactory, + [ + trustedForwarder.address, + assetAdmin.address, + 'ipfs://', + OperatorFilterSubscriptionContract.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await AssetContract.deployed(); + const RoyaltyManagerAsAdmin = RoyaltyManagerContract.connect(managerAdmin); + const splitterDeployerRole = + await RoyaltyManagerContract.SPLITTER_DEPLOYER_ROLE(); + await RoyaltyManagerAsAdmin.grantRole( + splitterDeployerRole, + AssetContract.address + ); + + // deploy wrapped TokenIdUtils contract + const TokenIdUtilsFactory = await ethers.getContractFactory( + 'TokenIdUtilsWrapped' + ); + const TokenIdUtilsContract = await TokenIdUtilsFactory.deploy(); + await TokenIdUtilsContract.deployed(); + + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + const CatalystContract = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await CatalystContract.deployed(); + + const AuthValidatorFactory = await ethers.getContractFactory( + 'AuthSuperValidator' + ); + const AuthValidatorContract = await AuthValidatorFactory.deploy( + authValidatorAdmin.address + ); + + await AuthValidatorContract.deployed(); + + const MockAssetReveal = await ethers.getContractFactory('MockAssetReveal'); + const MockAssetRevealContract = await MockAssetReveal.deploy(); + await MockAssetRevealContract.deployed(); + + // END DEPLOY DEPENDENCIES + + const AssetRevealFactory = await ethers.getContractFactory('AssetReveal'); + + const AssetRevealContract = await upgrades.deployProxy( + AssetRevealFactory, + [ + name, + version, + AssetContract.address, + AuthValidatorContract.address, + trustedForwarder.address, + assetAdmin.address, + ], + { + initializer: 'initialize', + } + ); + + await AssetRevealContract.deployed(); + + // SETUP VALIDATOR + await AuthValidatorContract.connect(authValidatorAdmin).setSigner( + AssetRevealContract.address, + backendAuthWallet.address + ); + + // SET UP ROLES + const AssetRevealContractAsUser = AssetRevealContract.connect(user); + const AssetRevealContractAsAdmin = AssetRevealContract.connect(assetAdmin); + + const MockMinterFactory = await ethers.getContractFactory('MockMinter'); + const MockMinterContract = await MockMinterFactory.deploy( + AssetContract.address + ); + const AssetContractAsAdmin = AssetContract.connect(assetAdmin); + // add mock minter as minter + const MinterRole = await AssetContract.MINTER_ROLE(); + const BurnerRole = await AssetContract.BURNER_ROLE(); + const AdminRole = await AssetContract.DEFAULT_ADMIN_ROLE(); + await AssetContractAsAdmin.grantRole(MinterRole, MockMinterContract.address); + + // add AssetReveal contracts as both MINTER and BURNER for Asset contract + await AssetContractAsAdmin.grantRole(MinterRole, AssetRevealContract.address); + await AssetContractAsAdmin.grantRole(BurnerRole, AssetRevealContract.address); + + // set admin as pauser + const PauserRole = await AssetRevealContract.PAUSER_ROLE(); + await AssetRevealContractAsAdmin.grantRole(PauserRole, assetAdmin.address); + // END SET UP ROLES + + // SET TIER 5 AS ALLOWED FOR INSTANT REVEAl + await AssetRevealContractAsAdmin.setTierInstantRevealAllowed(5, true); + + // SETUP USER WITH MINTED ASSETS + // mint a tier 5 asset with 10 copies + const unRevMintTx = await MockMinterContract.mintAsset( + user.address, + 10, // amount + 5, // tier + false, // revealed + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJA' // metadata hash + ); + const unRevResult = await unRevMintTx.wait(); + const unrevealedtokenId = unRevResult.events + .find((e: Event) => e.event === 'Minted') + .args.tokenId.toString(); + + // mint a tier 5 asset with 10 copies + const unRevMintTx2 = await MockMinterContract.mintAsset( + user.address, + 10, + 4, + false, + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJD' + ); + const unRevResult2 = await unRevMintTx2.wait(); + + const unrevealedtokenId2 = unRevResult2.events + .find((e: Event) => e.event === 'Minted') + .args.tokenId.toString(); + + // mint a revealed version, tier 5 asset with 10 copies + const revMintTx = await MockMinterContract.mintAsset( + user.address, + 10, + 5, + true, + 'QmZvGR5JNtSjSgSL9sD8V3LpSTHYXcfc9gy3CqptuoETJC' + ); + const revResult = await revMintTx.wait(); + + const revealedtokenId = revResult.events + .find((e: Event) => e.event === 'Minted') + .args.tokenId.toString(); + + // END SETUP USER WITH MINTED ASSETS + + // HELPER FUNCTIONS + const revealAsset = async ( + signature: string, + tokenId: number, + amounts: number[], + metadataHashes: string[], + revealHashes: string[] + ) => { + const tx = await AssetRevealContractAsUser.revealMint( + signature, + tokenId, + amounts, + metadataHashes, + revealHashes + ); + const result = await tx.wait(); + return result; + }; + + const revealAssetBatch = async ( + signature: string, + tokenIds: number[], + amounts: number[][], + metadataHashes: string[][], + revealHashes: string[][] + ) => { + const tx = await AssetRevealContractAsUser.revealBatchMint( + signature, + tokenIds, + amounts, + metadataHashes, + revealHashes + ); + const result = await tx.wait(); + return result; + }; + + const instantReveal = async ( + signature: string, + tokenId: number, + burnAmount: number, + mintAmounts: number[], + metadataHashes: string[], + revealHashes: string[] + ) => { + const tx = await AssetRevealContractAsUser.burnAndReveal( + signature, + tokenId, + burnAmount, + mintAmounts, + metadataHashes, + revealHashes + ); + const result = await tx.wait(); + return result; + }; + + const generateRevealSignature = async ( + revealer: string, + prevTokenId: number, + amounts: number[], + metadataHashes: string[], + revealHashes: string[] + ) => { + const signature = await revealSignature( + revealer, + prevTokenId, + amounts, + metadataHashes, + revealHashes, + AssetRevealContract, + backendAuthWallet + ); + return signature; + }; + + const generateBatchRevealSignature = async ( + revealer: string, + prevTokenIds: number[], + amounts: number[][], + metadataHashes: string[][], + revealHashes: string[][] + ) => { + const signature = await batchRevealSignature( + revealer, + prevTokenIds, + amounts, + metadataHashes, + revealHashes, + AssetRevealContract, + backendAuthWallet + ); + return signature; + }; + + const generateBurnAndRevealSignature = async ( + revealer: string, + prevTokenId: number, + amounts: number[], + metadataHashes: string[], + revealHashes: string[] + ) => { + const signature = await burnAndRevealSignature( + revealer, + prevTokenId, + amounts, + metadataHashes, + revealHashes, + AssetRevealContract, + backendAuthWallet + ); + return signature; + }; + + const pause = async () => { + await AssetRevealContractAsAdmin.pause(); + }; + + const unpause = async () => { + await AssetRevealContractAsAdmin.unpause(); + }; + + // END HELPER FUNCTIONS + + return { + generateRevealSignature, + generateBatchRevealSignature, + generateBurnAndRevealSignature, + revealAsset, + revealAssetBatch, + instantReveal, + pause, + unpause, + AssetRevealContract, + AssetRevealContractAsUser, + AssetRevealContractAsAdmin, + MockAssetRevealContract, + TokenIdUtilsContract, + AssetContract, + AuthValidatorContract, + trustedForwarder, + unrevealedtokenId, + unrevealedtokenId2, + revealedtokenId, + AdminRole, + PauserRole, + user, + assetAdmin, + }; +} diff --git a/packages/asset/test/fixtures/asset/assetRoyaltyFixture.ts b/packages/asset/test/fixtures/asset/assetRoyaltyFixture.ts new file mode 100644 index 0000000000..28eab90a91 --- /dev/null +++ b/packages/asset/test/fixtures/asset/assetRoyaltyFixture.ts @@ -0,0 +1,191 @@ +import {ethers, upgrades} from 'hardhat'; +import {DEFAULT_SUBSCRIPTION} from '../../../data/constants'; + +const DEFAULT_BPS = 300; + +export function generateAssetId(creator: string, assetNumber: number) { + const hex = assetNumber.toString(16); + const hexLength = hex.length; + let zeroAppends = ''; + const zeroAppendsLength = 24 - hexLength; + for (let i = 0; i < zeroAppendsLength; i++) { + zeroAppends = zeroAppends + '0'; + } + return `0x${zeroAppends}${hex}${creator.slice(2)}`; +} + +export async function assetRoyaltyDistribution() { + const [ + deployer, + assetAdmin, + assetMinter, + buyer, + seller, + commonRoyaltyReceiver, + managerAdmin, + contractRoyaltySetter, + user, + royaltyReceiver, + commonRoyaltyReceiver2, + royaltyReceiver2, + creator, + mockMarketplace1, + mockMarketplace2, + ] = await ethers.getSigners(); + + // test upgradeable contract using '@openzeppelin/hardhat-upgrades' + + const TrustedForwarderFactory = await ethers.getContractFactory( + 'MockTrustedForwarder' + ); + const TrustedForwarder = await TrustedForwarderFactory.deploy(); + + const NonTrustedForwarder = await TrustedForwarderFactory.deploy(); + + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketplace1.address, mockMarketplace2.address] + ); + + // Operator Filter Registrant + const OperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + + // Provide: address _owner, address _localRegistry + const OperatorFilterSubscriptionContract = + await OperatorFilterSubscriptionFactory.deploy( + assetAdmin.address, + operatorFilterRegistry.address + ); + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + TrustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const AssetFactory = await ethers.getContractFactory('Asset'); + const Asset = await upgrades.deployProxy( + AssetFactory, + [ + TrustedForwarder.address, + assetAdmin.address, + 'ipfs://', + OperatorFilterSubscriptionContract.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + await Asset.deployed(); + + const FallbackRegistryFactory = await ethers.getContractFactory( + 'FallbackRegistry' + ); + const FallbackRegistry = await FallbackRegistryFactory.deploy( + deployer.address + ); + + const RoyaltyRegistryFactory = await ethers.getContractFactory( + 'RoyaltyRegistry' + ); + const RoyaltyRegistry = await RoyaltyRegistryFactory.deploy( + '0x0000000000000000000000000000000000000000' + ); + + const RoyaltyEngineFactory = await ethers.getContractFactory( + 'RoyaltyEngineV1' + ); + const RoyaltyEngineV1 = await RoyaltyEngineFactory.deploy( + FallbackRegistry.address + ); + + await RoyaltyEngineV1.initialize(deployer.address, RoyaltyRegistry.address); + + const MockMarketPlaceFactory = await ethers.getContractFactory( + 'MockMarketplace' + ); + const mockMarketplace = await MockMarketPlaceFactory.deploy( + RoyaltyEngineV1.address + ); + + const TestERC20Factory = await ethers.getContractFactory('TestERC20'); + const ERC20 = await TestERC20Factory.deploy('TestERC20', 'T'); + + const assetAdminRole = await Asset.DEFAULT_ADMIN_ROLE(); + const assetMinterRole = await Asset.MINTER_ROLE(); + await Asset.connect(assetAdmin).grantRole( + assetMinterRole, + assetMinter.address + ); + const assetAsMinter = Asset.connect(assetMinter); + const managerAdminRole = await RoyaltyManagerContract.DEFAULT_ADMIN_ROLE(); + const contractRoyaltySetterRole = + await RoyaltyManagerContract.CONTRACT_ROYALTY_SETTER_ROLE(); + const AssetAsSeller = Asset.connect(seller); + const ERC20AsBuyer = ERC20.connect(buyer); + const RoyaltyManagerAsAdmin = RoyaltyManagerContract.connect(managerAdmin); + const RoyaltyManagerAsRoyaltySetter = RoyaltyManagerContract.connect( + contractRoyaltySetter + ); + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + Asset.address, + DEFAULT_BPS + ); + const splitterDeployerRole = + await RoyaltyManagerContract.SPLITTER_DEPLOYER_ROLE(); + await RoyaltyManagerAsAdmin.grantRole(splitterDeployerRole, Asset.address); + return { + Asset, + ERC20, + RoyaltyManagerContract, + mockMarketplace, + AssetAsSeller, + ERC20AsBuyer, + deployer, + seller, + buyer, + user, + commonRoyaltyReceiver, + royaltyReceiver, + RoyaltyRegistry, + RoyaltyManagerAsAdmin, + commonRoyaltyReceiver2, + royaltyReceiver2, + creator, + assetAdminRole, + contractRoyaltySetter, + assetAdmin, + managerAdminRole, + contractRoyaltySetterRole, + RoyaltyManagerAsRoyaltySetter, + assetAsMinter, + TrustedForwarder, + NonTrustedForwarder, + }; +} diff --git a/packages/asset/test/fixtures/authValidatorFixture.ts b/packages/asset/test/fixtures/authValidatorFixture.ts new file mode 100644 index 0000000000..586ba69f54 --- /dev/null +++ b/packages/asset/test/fixtures/authValidatorFixture.ts @@ -0,0 +1,35 @@ +import {ethers} from 'hardhat'; +import {createMockDigest, createMockSignature} from '../utils/createSignature'; +const runSetup = async () => { + const [deployer, authValidatorAdmin, backendSigner] = + await ethers.getSigners(); + + const AuthValidatorFactory = await ethers.getContractFactory( + 'AuthSuperValidator' + ); + const AuthValidatorContract = await AuthValidatorFactory.connect( + deployer + ).deploy(authValidatorAdmin.address); + await AuthValidatorContract.deployed(); + + const AuthValidatorContractAsAdmin = await AuthValidatorContract.connect( + authValidatorAdmin + ); + + const MockContractFactory = await ethers.getContractFactory('MockAsset'); + const MockContract = await MockContractFactory.connect(deployer).deploy(); + await MockContract.deployed(); + + return { + authValidatorAdmin, + AuthValidatorContract, + AuthValidatorContractAsAdmin, + MockContract, + backendSigner, + deployer, + createMockDigest, + createMockSignature, + }; +}; + +export default runSetup; diff --git a/packages/asset/test/fixtures/catalyst/catalystFixture.ts b/packages/asset/test/fixtures/catalyst/catalystFixture.ts new file mode 100644 index 0000000000..674e492738 --- /dev/null +++ b/packages/asset/test/fixtures/catalyst/catalystFixture.ts @@ -0,0 +1,117 @@ +import {ethers, upgrades} from 'hardhat'; +import { + DEFAULT_SUBSCRIPTION, + CATALYST_BASE_URI, + CATALYST_IPFS_CID_PER_TIER, +} from '../../../data/constants'; + +export async function runCatalystSetup() { + const [ + deployer, + upgradeAdmin, + catalystMinter, + catalystAdmin, + catalystRoyaltyRecipient, + trustedForwarder, + user1, + user2, + mockMarketplace1, + mockMarketplace2, + commonRoyaltyReceiver, + managerAdmin, + contractRoyaltySetter, + ] = await ethers.getSigners(); + + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketplace1.address, mockMarketplace2.address] + ); + + // Operator Filter Registrant + const OperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + + // Provide: address _owner, address _localRegistry + const OperatorFilterSubscriptionContract = + await OperatorFilterSubscriptionFactory.deploy( + catalystAdmin.address, + operatorFilterRegistry.address + ); + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + trustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + const catalyst = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscriptionContract.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + await catalyst.deployed(); + + // grant burner role to catalystMinter + const catMinterRole = await catalyst.BURNER_ROLE(); + await catalyst + .connect(catalystAdmin) + .grantRole(catMinterRole, catalystMinter.address); + + const catalystAsAdmin = await catalyst.connect(catalystAdmin); + const minterRole = await catalyst.MINTER_ROLE(); + const catalystAdminRole = await catalyst.DEFAULT_ADMIN_ROLE(); + const catalystAsMinter = await catalyst.connect(catalystMinter); + const catalystAsBurner = await catalyst.connect(catalystMinter); + return { + deployer, + catalyst, + user1, + user2, + minterRole, + catalystAsAdmin, + catalystAsMinter, + catalystAdminRole, + upgradeAdmin, + catalystMinter, + catalystAsBurner, + catalystAdmin, + catalystRoyaltyRecipient, + trustedForwarder, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + }; +} diff --git a/packages/asset/test/fixtures/catalyst/catalystRoyaltyFixture.ts b/packages/asset/test/fixtures/catalyst/catalystRoyaltyFixture.ts new file mode 100644 index 0000000000..7fcfb50408 --- /dev/null +++ b/packages/asset/test/fixtures/catalyst/catalystRoyaltyFixture.ts @@ -0,0 +1,156 @@ +import {ethers, upgrades} from 'hardhat'; +import { + CATALYST_BASE_URI, + CATALYST_IPFS_CID_PER_TIER, + DEFAULT_SUBSCRIPTION, +} from '../../../data/constants'; + +export async function catalystRoyaltyDistribution() { + const [ + deployer, + catalystMinter, + catalystAdmin, + trustedForwarder, + seller, + buyer, + royaltyReceiver, + user, + commonRoyaltyReceiver2, + royaltyReceiver2, + creator, + commonRoyaltyReceiver, + managerAdmin, + contractRoyaltySetter, + assetAdmin, + mockMarketplace1, + mockMarketplace2, + ] = await ethers.getSigners(); + + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketplace1.address, mockMarketplace2.address] + ); + + const OperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + const OperatorFilterSubscription = + await OperatorFilterSubscriptionFactory.deploy( + assetAdmin.address, + operatorFilterRegistry.address + ); + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + trustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const CatalystFactory = await ethers.getContractFactory('Catalyst'); + const catalystContract = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + trustedForwarder.address, + OperatorFilterSubscription.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + await catalystContract.deployed(); + + const FallbackRegistryFactory = await ethers.getContractFactory( + 'FallbackRegistry' + ); + const FallbackRegistry = await FallbackRegistryFactory.deploy( + deployer.address + ); + + const RoyaltyRegistryFactory = await ethers.getContractFactory( + 'RoyaltyRegistry' + ); + const RoyaltyRegistry = await RoyaltyRegistryFactory.deploy( + '0x0000000000000000000000000000000000000000' + ); + + const RoyaltyEngineFactory = await ethers.getContractFactory( + 'RoyaltyEngineV1' + ); + const RoyaltyEngineV1 = await RoyaltyEngineFactory.deploy( + FallbackRegistry.address + ); + + await RoyaltyEngineV1.initialize(deployer.address, RoyaltyRegistry.address); + + const MockMarketPlaceFactory = await ethers.getContractFactory( + 'MockMarketplace' + ); + const mockMarketplace = await MockMarketPlaceFactory.deploy( + RoyaltyEngineV1.address + ); + + const TestERC20Factory = await ethers.getContractFactory('TestERC20'); + const ERC20 = await TestERC20Factory.deploy('TestERC20', 'T'); + + // Set up roles + const catalystAsMinter = catalystContract.connect(catalystMinter); + const managerAdminRole = await RoyaltyManagerContract.DEFAULT_ADMIN_ROLE(); + const contractRoyaltySetterRole = + await RoyaltyManagerContract.CONTRACT_ROYALTY_SETTER_ROLE(); + const ERC20AsBuyer = ERC20.connect(buyer); + const managerAsAdmin = RoyaltyManagerContract.connect(managerAdmin); + const managerAsRoyaltySetter = RoyaltyManagerContract.connect( + contractRoyaltySetter + ); + // End set up roles + + return { + ERC20, + manager: RoyaltyManagerContract, + mockMarketplace, + ERC20AsBuyer, + deployer, + seller, + buyer, + user, + commonRoyaltyReceiver, + royaltyReceiver, + RoyaltyRegistry, + managerAsAdmin, + commonRoyaltyReceiver2, + royaltyReceiver2, + creator, + catalystAsMinter, + contractRoyaltySetter, + managerAdminRole, + contractRoyaltySetterRole, + managerAsRoyaltySetter, + }; +} diff --git a/packages/asset/test/fixtures/operatorFilterFixture.ts b/packages/asset/test/fixtures/operatorFilterFixture.ts new file mode 100644 index 0000000000..3811bb4eed --- /dev/null +++ b/packages/asset/test/fixtures/operatorFilterFixture.ts @@ -0,0 +1,198 @@ +import {ethers, upgrades} from 'hardhat'; +import {setupUsers} from '../../util'; +import { + DEFAULT_SUBSCRIPTION, + CATALYST_BASE_URI, + CATALYST_IPFS_CID_PER_TIER, +} from '../../data/constants'; + +const DEFAULT_BPS = 300; + +export async function setupOperatorFilter() { + const [ + deployer, + upgradeAdmin, + filterOperatorSubscription, + catalystAdmin, + catalystMinter, + assetAdmin, + user1, + user2, + user3, + user4, + commonRoyaltyReceiver, + managerAdmin, + contractRoyaltySetter, + ] = await ethers.getSigners(); + + const TrustedForwarderFactory = await ethers.getContractFactory( + 'MockTrustedForwarder' + ); + const TrustedForwarder = await TrustedForwarderFactory.deploy(); + + const MockERC1155MarketPlace1Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace1' + ); + + const mockMarketPlace1 = await MockERC1155MarketPlace1Factory.deploy(); + await mockMarketPlace1.deployed(); + + const MockERC1155MarketPlace2Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace2' + ); + + const mockMarketPlace2 = await MockERC1155MarketPlace2Factory.deploy(); + await mockMarketPlace2.deployed(); + + const MockERC1155MarketPlace3Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace3' + ); + + const mockMarketPlace3 = await MockERC1155MarketPlace3Factory.deploy(); + await mockMarketPlace3.deployed(); + + const MockERC1155MarketPlace4Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace4' + ); + + const mockMarketPlace4 = await MockERC1155MarketPlace4Factory.deploy(); + await mockMarketPlace4.deployed(); + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketPlace1.address, mockMarketPlace2.address] + ); + await operatorFilterRegistry.deployed(); + const operatorFilterRegistryAsSubscription = operatorFilterRegistry.connect( + await ethers.getSigner(filterOperatorSubscription.address) + ); + const tnx = await operatorFilterRegistryAsSubscription.registerAndCopyEntries( + filterOperatorSubscription.address, + DEFAULT_SUBSCRIPTION + ); + await tnx.wait(); + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + TrustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const AssetFactory = await ethers.getContractFactory('MockAsset'); + const Asset = await upgrades.deployProxy( + AssetFactory, + [ + TrustedForwarder.address, + assetAdmin.address, + 'ipfs://', + filterOperatorSubscription.address, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + + const defaultAdminRole = await Asset.DEFAULT_ADMIN_ROLE(); + + let MockOperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + + MockOperatorFilterSubscriptionFactory = + await MockOperatorFilterSubscriptionFactory.connect(deployer); + + const operatorFilterSubscription = + await MockOperatorFilterSubscriptionFactory.deploy( + deployer.address, + operatorFilterRegistry.address + ); + + const operatorFilterRegistryAsOwner = await operatorFilterRegistry.connect( + deployer + ); + + const CatalystFactory = await ethers.getContractFactory('MockCatalyst'); + const Catalyst = await upgrades.deployProxy( + CatalystFactory, + [ + CATALYST_BASE_URI, + TrustedForwarder.address, + operatorFilterSubscription.address, + catalystAdmin.address, // DEFAULT_ADMIN_ROLE + catalystMinter.address, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManagerContract.address, + ], + { + initializer: 'initialize', + } + ); + await Catalyst.deployed(); + + const tnx2 = await Asset.setRegistryAndSubscribe( + operatorFilterRegistry.address, + filterOperatorSubscription.address + ); + await tnx2.wait(); + + const tnx3 = await Catalyst.setRegistryAndSubscribe( + operatorFilterRegistry.address, + operatorFilterSubscription.address + ); + await tnx3.wait(); + const users = await setupUsers( + [user1.address, user2.address, user3.address, user4.address], + { + Asset, + Catalyst, + } + ); + + return { + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + operatorFilterRegistry, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + users, + deployer, + upgradeAdmin, + Asset, + DEFAULT_SUBSCRIPTION, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + Catalyst, + TrustedForwarder, + assetAdmin, + commonRoyaltyReceiver, + DEFAULT_BPS, + RoyaltyManagerContract, + catalystAdmin, + catalystMinter, + defaultAdminRole, + user1, + }; +} diff --git a/packages/asset/test/fixtures/tokenIdUtilsFixture.ts b/packages/asset/test/fixtures/tokenIdUtilsFixture.ts new file mode 100644 index 0000000000..e476915d88 --- /dev/null +++ b/packages/asset/test/fixtures/tokenIdUtilsFixture.ts @@ -0,0 +1,50 @@ +import {ethers} from 'hardhat'; + +export async function runTokenIdUtilsSetup() { + const TokenIdUtils = await ethers.getContractFactory('TokenIdUtilsWrapped'); + const tokenIdUtils = await TokenIdUtils.deploy(); + await tokenIdUtils.deployed(); + const [minter] = await ethers.getSigners(); + + const generateTokenId = async ( + creator = minter.address, + tier = 1, + creatorNonce = 1, + revealNonce = 0, + bridged = false + ) => { + const tokenId = await tokenIdUtils.generateTokenId( + creator, + tier, + creatorNonce, + revealNonce, + bridged + ); + return tokenId; + }; + + const TIER_MASK = await tokenIdUtils.TIER_MASK(); + const TIER_SHIFT = (await tokenIdUtils.TIER_SHIFT()).toNumber(); + const NONCE_MASK = await tokenIdUtils.NONCE_MASK(); + const NONCE_SHIFT = (await tokenIdUtils.NONCE_SHIFT()).toNumber(); + const REVEAL_NONCE_MASK = await tokenIdUtils.REVEAL_NONCE_MASK(); + const REVEAL_NONCE_SHIFT = ( + await tokenIdUtils.REVEAL_NONCE_SHIFT() + ).toNumber(); + const BRIDGED_MASK = await tokenIdUtils.BRIDGED_MASK(); + const BRIDGED_SHIFT = (await tokenIdUtils.BRIDGED_SHIFT()).toNumber(); + + return { + TIER_MASK, + TIER_SHIFT, + NONCE_MASK, + NONCE_SHIFT, + REVEAL_NONCE_MASK, + REVEAL_NONCE_SHIFT, + BRIDGED_MASK, + BRIDGED_SHIFT, + address: minter.address, + tokenIdUtils, + generateTokenId, + }; +} diff --git a/packages/asset/test/utils/createSignature.ts b/packages/asset/test/utils/createSignature.ts new file mode 100644 index 0000000000..53aae44e95 --- /dev/null +++ b/packages/asset/test/utils/createSignature.ts @@ -0,0 +1,160 @@ +import {ethers} from 'ethers'; +import hre from 'hardhat'; +import {Contract} from 'ethers'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; + +const createAssetMintSignature = async ( + creator: string, + tier: number, + amount: number, + revealed: boolean, + metadataHash: string, + contract: Contract, + signer: SignerWithAddress +) => { + const AssetCreateContract = contract; + const nonce = await AssetCreateContract.signatureNonces(creator); + + const data = { + types: { + Mint: [ + {name: 'creator', type: 'address'}, + {name: 'nonce', type: 'uint16'}, + {name: 'tier', type: 'uint8'}, + {name: 'amount', type: 'uint256'}, + {name: 'revealed', type: 'bool'}, + {name: 'metadataHash', type: 'string'}, + ], + }, + domain: { + name: 'Sandbox Asset Create', + version: '1.0', + chainId: hre.network.config.chainId, + verifyingContract: AssetCreateContract.address, + }, + message: { + creator, + nonce, + tier, + amount, + revealed, + metadataHash, + }, + }; + + const signature = await signer._signTypedData( + data.domain, + data.types, + data.message + ); + return signature; +}; + +const createMultipleAssetsMintSignature = async ( + creator: string, + tiers: number[], + amounts: number[], + revealed: boolean[], + metadataHashes: string[], + contract: Contract, + signer: SignerWithAddress +) => { + const AssetCreateContract = contract; + const nonce = await AssetCreateContract.signatureNonces(creator); + const data = { + types: { + MintBatch: [ + {name: 'creator', type: 'address'}, + {name: 'nonce', type: 'uint16'}, + {name: 'tiers', type: 'uint8[]'}, + {name: 'amounts', type: 'uint256[]'}, + {name: 'revealed', type: 'bool[]'}, + {name: 'metadataHashes', type: 'string[]'}, + ], + }, + domain: { + name: 'Sandbox Asset Create', + version: '1.0', + chainId: hre.network.config.chainId, + verifyingContract: AssetCreateContract.address, + }, + message: { + creator, + nonce, + tiers, + amounts, + revealed, + metadataHashes, + }, + }; + + const signature = await signer._signTypedData( + data.domain, + data.types, + data.message + ); + return signature; +}; + +const createMockSignature = async ( + creator: string, + signer: SignerWithAddress +) => { + const data = { + types: { + Basic: [{name: 'creator', type: 'address'}], + }, + domain: { + name: 'The Sandbox', + version: '1.0', + chainId: hre.network.config.chainId, + }, + message: { + creator, + }, + }; + + const signature = await signer._signTypedData( + data.domain, + data.types, + data.message + ); + + const digest = ethers.utils._TypedDataEncoder.hash( + data.domain, + data.types, + data.message + ); + + return {signature, digest}; +}; + +const createMockDigest = async (creator: string) => { + const data = { + types: { + Basic: [{name: 'creator', type: 'address'}], + }, + domain: { + name: 'The Sandbox', + version: '1.0', + chainId: hre.network.config.chainId, + }, + message: { + creator, + }, + }; + const digest = ethers.utils._TypedDataEncoder.hash( + data.domain, + data.types, + data.message + ); + + return digest; +}; + +export { + createAssetMintSignature, + createMultipleAssetsMintSignature, + createMockSignature, + createMockDigest, +}; diff --git a/packages/asset/test/utils/events.ts b/packages/asset/test/utils/events.ts new file mode 100644 index 0000000000..fe18151f4d --- /dev/null +++ b/packages/asset/test/utils/events.ts @@ -0,0 +1,9 @@ +import {Event} from 'ethers'; + +export const findEventByName = (events: Event[], eventName: string) => { + return events.find((event) => event.event === eventName); +}; + +export const findAllEventsByName = (events: Event[], eventName: string) => { + return events.filter((event) => event.event === eventName); +}; diff --git a/packages/asset/test/utils/interfaceIds.ts b/packages/asset/test/utils/interfaceIds.ts new file mode 100644 index 0000000000..2ecf7170aa --- /dev/null +++ b/packages/asset/test/utils/interfaceIds.ts @@ -0,0 +1,8 @@ +export const ERC165InterfaceId = '0x01ffc9a7'; +export const ERC1155InterfaceId = '0xd9b67a26'; +export const ERC1155MetadataURIInterfaceId = '0x0e89341c'; +export const AccessControlInterfaceId = '0x7965db0b'; +export const ERC2981InterfaceId = '0x2a55205a'; +export const RoyaltyUGCInterfaceId = '0xa30b4db9'; +export const RoyaltyMultiDistributorInterfaceId = '0xf1e82fd0'; +export const RoyaltyMultiRecipientsInterfaceId = '0xfd90e897'; diff --git a/packages/asset/test/utils/revealSignature.ts b/packages/asset/test/utils/revealSignature.ts new file mode 100644 index 0000000000..22eee49666 --- /dev/null +++ b/packages/asset/test/utils/revealSignature.ts @@ -0,0 +1,133 @@ +import hre from 'hardhat'; +import {Contract} from 'ethers'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; + +async function burnAndRevealSignature( + recipient: string, + prevTokenId: number, + amounts: number[], + metadataHashes: string[], + revealHashes: string[], + contract: Contract, + signer: SignerWithAddress +): Promise { + const AssetRevealContract = contract; + const data = { + types: { + InstantReveal: [ + {name: 'recipient', type: 'address'}, + {name: 'prevTokenId', type: 'uint256'}, + {name: 'amounts', type: 'uint256[]'}, + {name: 'metadataHashes', type: 'string[]'}, + {name: 'revealHashes', type: 'bytes32[]'}, + ], + }, + domain: { + name: 'Sandbox Asset Reveal', + version: '1.0', + chainId: hre.network.config.chainId, + verifyingContract: AssetRevealContract.address, + }, + message: { + recipient, + prevTokenId, + amounts, + metadataHashes, + revealHashes, + }, + }; + const signature = await signer._signTypedData( + data.domain, + data.types, + data.message + ); + return signature; +} + +async function batchRevealSignature( + recipient: string, + prevTokenIds: number[], + amounts: number[][], + metadataHashes: string[][], + revealHashes: string[][], + contract: Contract, + signer: SignerWithAddress +): Promise { + const AssetRevealContract = contract; + const data = { + types: { + BatchReveal: [ + {name: 'recipient', type: 'address'}, + {name: 'prevTokenIds', type: 'uint256[]'}, + {name: 'amounts', type: 'uint256[][]'}, + {name: 'metadataHashes', type: 'string[][]'}, + {name: 'revealHashes', type: 'bytes32[][]'}, + ], + }, + domain: { + name: 'Sandbox Asset Reveal', + version: '1.0', + chainId: hre.network.config.chainId, + verifyingContract: AssetRevealContract.address, + }, + message: { + recipient, + prevTokenIds, + amounts, + metadataHashes, + revealHashes, + }, + }; + + const signature = await signer._signTypedData( + data.domain, + data.types, + data.message + ); + return signature; +} + +async function revealSignature( + recipient: string, + prevTokenId: number, + amounts: number[], + metadataHashes: string[], + revealHashes: string[], + contract: Contract, + signer: SignerWithAddress +): Promise { + const AssetRevealContract = contract; + const data = { + types: { + Reveal: [ + {name: 'recipient', type: 'address'}, + {name: 'prevTokenId', type: 'uint256'}, + {name: 'amounts', type: 'uint256[]'}, + {name: 'metadataHashes', type: 'string[]'}, + {name: 'revealHashes', type: 'bytes32[]'}, + ], + }, + domain: { + name: 'Sandbox Asset Reveal', + version: '1.0', + chainId: hre.network.config.chainId, + verifyingContract: AssetRevealContract.address, + }, + message: { + recipient, + prevTokenId, + amounts, + metadataHashes, + revealHashes, + }, + }; + + const signature = await signer._signTypedData( + data.domain, + data.types, + data.message + ); + return signature; +} + +export {burnAndRevealSignature, batchRevealSignature, revealSignature}; diff --git a/packages/asset/tsconfig.json b/packages/asset/tsconfig.json new file mode 100644 index 0000000000..574e785c71 --- /dev/null +++ b/packages/asset/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } +} diff --git a/packages/asset/util.ts b/packages/asset/util.ts new file mode 100644 index 0000000000..4ad6401463 --- /dev/null +++ b/packages/asset/util.ts @@ -0,0 +1,231 @@ +/* eslint-disable mocha/no-exports */ +import {BigNumber} from '@ethersproject/bignumber'; +import { + Contract, + ContractReceipt, + ContractTransaction, + Event, + utils, +} from 'ethers'; +import {Receipt} from 'hardhat-deploy/types'; +import {Result} from 'ethers/lib/utils'; +import {deployments, ethers, network} from 'hardhat'; +import {FixtureFunc} from 'hardhat-deploy/dist/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +export async function sequentially( + arr: Array, + callbackfn: (value: S, index: number, array: S[]) => Promise +): Promise { + const ret = []; + for (let i = 0; i < arr.length; i++) { + ret.push(await callbackfn(arr[i], i, arr)); + } + return ret; +} + +export async function mine(): Promise { + await ethers.provider.send('evm_mine', []); +} + +export async function increaseTime( + numSec: number, + callMine = true +): Promise { + // must do something (mine, send a tx) to move the time + await ethers.provider.send('evm_increaseTime', [numSec]); + if (callMine) await mine(); +} + +export async function getTime(): Promise { + const latestBlock = await ethers.provider.getBlock('latest'); + return latestBlock.timestamp; +} + +export async function setNextBlockTime( + time: number, + callMine = false +): Promise { + // must do something (mine, send a tx) to move the time + await ethers.provider.send('evm_setNextBlockTimestamp', [time]); + if (callMine) await mine(); +} + +type Test = { + title: string; + subTests?: Test[]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + test: any; +}; + +export function recurseTests(test: Test): void { + /* eslint-disable mocha/no-setup-in-describe */ + if (test.subTests) { + describe(test.title, function () { + if (test.subTests) { + for (const subTest of test.subTests) { + recurseTests(subTest); + } + } + }); + } else { + it(test.title, test.test); + } + /* eslint-enable mocha/no-setup-in-describe */ +} + +export function toWei(number: string | number | BigNumber): BigNumber { + return BigNumber.from(number).mul('1000000000000000000'); +} + +export function cubeRoot6(bigNum: BigNumber): BigNumber { + const DECIMALS_18 = BigNumber.from(1).mul('1000000000000000000'); + const a = bigNum.mul(DECIMALS_18); + const base = BigNumber.from(2); + const root = BigNumber.from(3); + let tmp = a.add(base).div(root); + let c = a; + while (tmp.lt(c)) { + c = tmp; + const tmpSquare = tmp.mul(tmp); + const numerator = a.div(tmpSquare).add(tmp.mul(base)); + tmp = numerator.div(root); + } + return c; +} + +export async function findEvents( + contract: Contract, + event: string, + blockHash: string +): Promise { + const filter = contract.filters[event](); + return await contract.queryFilter(filter, blockHash); +} + +export type EventWithArgs = Event & {args: Result}; + +export async function expectReceiptEventWithArgs( + receipt: ContractReceipt, + name: string +): Promise { + if (!receipt.events) { + throw new Error('no events'); + } + for (const event of receipt.events) { + if (event.event === name) { + if (!event.args) { + throw new Error('event has no args'); + } + return event as EventWithArgs; + } + } + throw new Error('no matching events'); +} + +export async function expectEventWithArgs( + contract: Contract, + receipt: ContractReceipt, + event: string +): Promise { + const events = await findEvents(contract, event, receipt.blockHash); + if (events.length == 0) { + throw new Error('no events'); + } + if (!events[0].args) { + throw new Error('event has no args'); + } + return events[0] as EventWithArgs; +} + +export async function expectEventWithArgsFromReceipt( + contract: Contract, + receipt: Receipt, + event: string +): Promise { + const events = await findEvents(contract, event, receipt.blockHash); + if (events.length == 0) { + throw new Error('no events'); + } + if (!events[0].args) { + throw new Error('event has no args'); + } + return events[0] as EventWithArgs; +} + +export function waitFor( + p: Promise +): Promise { + return p.then((tx) => tx.wait()); +} + +type Contracts = Record; + +export async function setupUsers( + addresses: string[], + contracts: T +): Promise<({address: string} & T)[]> { + const users: ({address: string} & T)[] = []; + for (const address of addresses) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const user: any = {address}; + for (const key of Object.keys(contracts)) { + user[key] = contracts[key].connect(await ethers.getSigner(address)); + } + users.push(user); + } + return users; +} + +export async function setupUser( + address: string, + contracts: T +): Promise<{address: string} & T> { + const users = await setupUsers([address], contracts); + return users[0]; +} + +export function getNftIndex(id: BigNumber): number { + // js bitwise & operands are converted to 32-bit integers + const idAsHexString = utils.hexValue(id); + const slicedId = Number('0x' + idAsHexString.slice(48, 56)); + const SLICED_NFT_INDEX_MASK = Number('0x7F800000'); + return (slicedId & SLICED_NFT_INDEX_MASK) >>> 23; +} + +export function getAssetChainIndex(id: BigNumber): number { + // js bitwise & operands are converted to 32-bit integers + const idAsHexString = utils.hexValue(id); + const slicedId = Number('0x' + idAsHexString.slice(42, 50)); + const SLICED_CHAIN_INDEX_MASK = Number('0x7F800000'); + return (slicedId & SLICED_CHAIN_INDEX_MASK) >>> 23; +} + +export async function evmRevertToInitialState(): Promise { + console.log('Revert to initial snapshot, calling reset'); + // This revert the evm state. + await network.provider.request({ + method: 'hardhat_reset', + params: [network.config], + }); +} + +export function withSnapshot( + tags: string | string[] = [], + func: FixtureFunc = async () => { + return {}; + } +): (options?: O) => Promise { + return deployments.createFixture( + async (env: HardhatRuntimeEnvironment, options?: O) => { + // TODO: This has problems with solidity-coverage, when the fix that we can use it + // TODO: We need a way to revert to initial state!!! + // await evmRevertToInitialState(); + await deployments.fixture(tags, { + fallbackToGlobal: false, + keepExistingDeployments: false, + }); + return func(env, options); + } + ); +} diff --git a/packages/dependency-metatx/contracts/ERC2771Handler.sol b/packages/dependency-metatx/contracts/ERC2771Handler.sol index 6589ac3010..0fd84c38d8 100644 --- a/packages/dependency-metatx/contracts/ERC2771Handler.sol +++ b/packages/dependency-metatx/contracts/ERC2771Handler.sol @@ -44,4 +44,16 @@ contract ERC2771Handler is ERC2771HandlerAbstract { function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) { return forwarder == _trustedForwarder; } + + /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise + /// @return sender the calculated address of the sender + function _msgSender() internal view virtual override returns (address sender) { + return super._msgSender(); + } + + /// @notice if the call is from the trusted forwarder the sender is removed from calldata + /// @return the calldata without the sender + function _msgData() internal view virtual override returns (bytes calldata) { + return super._msgData(); + } } diff --git a/packages/dependency-metatx/contracts/ERC2771HandlerAbstract.sol b/packages/dependency-metatx/contracts/ERC2771HandlerAbstract.sol index 07828a8623..600b15cf1d 100644 --- a/packages/dependency-metatx/contracts/ERC2771HandlerAbstract.sol +++ b/packages/dependency-metatx/contracts/ERC2771HandlerAbstract.sol @@ -38,6 +38,6 @@ abstract contract ERC2771HandlerAbstract { /// @notice return true if the forwarder is the trusted forwarder /// @param forwarder trusted forwarder address to check /// @return true if the address is the same as the trusted forwarder - /// @dev TODO: IMPLEMENT!!! + /// @dev this function must be IMPLEMENTED function _isTrustedForwarder(address forwarder) internal view virtual returns (bool); } diff --git a/packages/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol b/packages/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol index 6ba4152f86..ff5a2f6047 100644 --- a/packages/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol +++ b/packages/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol @@ -42,6 +42,7 @@ contract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract { /// @notice set the address of the trusted forwarder /// @param newForwarder the address of the new forwarder. function _setTrustedForwarder(address newForwarder) internal virtual { + require(newForwarder != _trustedForwarder, "ERC2771HandlerUpgradeable: forwarder already set"); emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender()); _trustedForwarder = newForwarder; } @@ -53,5 +54,17 @@ contract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract { return forwarder == _trustedForwarder; } + /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise + /// @return sender the calculated address of the sender + function _msgSender() internal view virtual override returns (address sender) { + return super._msgSender(); + } + + /// @notice if the call is from the trusted forwarder the sender is removed from calldata + /// @return the calldata without the sender + function _msgData() internal view virtual override returns (bytes calldata) { + return super._msgData(); + } + uint256[49] private __gap; } diff --git a/packages/dependency-metatx/contracts/test/MockTrustedForwarder.sol b/packages/dependency-metatx/contracts/test/MockTrustedForwarder.sol new file mode 100644 index 0000000000..0367b1bc49 --- /dev/null +++ b/packages/dependency-metatx/contracts/test/MockTrustedForwarder.sol @@ -0,0 +1,22 @@ +//SPDX-License-Identifier: MIT +// solhint-disable-next-line compiler-version +pragma solidity ^0.8.2; + +contract MockTrustedForwarder { + struct ForwardRequest { + address from; + address to; + uint256 value; + uint256 gasLimit; + bytes data; + } + + function execute(ForwardRequest calldata req) public payable returns (bool, bytes memory) { + (bool success, bytes memory returndata) = req.to.call{gas: req.gasLimit, value: req.value}( + abi.encodePacked(req.data, req.from) + ); + assert(gasleft() > req.gasLimit / 63); + require(success, "Call execution failed"); + return (success, returndata); + } +} diff --git a/packages/dependency-operator-filter/.eslintignore b/packages/dependency-operator-filter/.eslintignore new file mode 100644 index 0000000000..a77e23ebbf --- /dev/null +++ b/packages/dependency-operator-filter/.eslintignore @@ -0,0 +1,16 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts + +# generated docs +generated-markups + +# editors +.idea diff --git a/packages/dependency-operator-filter/.eslintrc.js b/packages/dependency-operator-filter/.eslintrc.js new file mode 100644 index 0000000000..e734de4058 --- /dev/null +++ b/packages/dependency-operator-filter/.eslintrc.js @@ -0,0 +1,41 @@ +const path = require('path'); +const tsconfigPath = path.join(__dirname, 'tsconfig.json'); +module.exports = { + root: true, + extends: [ + 'eslint:recommended', + 'plugin:mocha/recommended', + 'plugin:prettier/recommended', + ], + parserOptions: { + ecmaVersion: 2020, + }, + plugins: ['mocha'], + env: { + commonjs: true, + node: true, + mocha: true, + }, + overrides: [ + { + files: ['*.ts'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: [tsconfigPath], + ecmaVersion: 2020, + sourceType: 'module', + }, + plugins: ['mocha', '@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:mocha/recommended', + 'plugin:prettier/recommended', + ], + rules: { + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-floating-promises': 'error', + }, + }, + ], +}; diff --git a/packages/dependency-operator-filter/.gitignore b/packages/dependency-operator-filter/.gitignore new file mode 100644 index 0000000000..04e3058747 --- /dev/null +++ b/packages/dependency-operator-filter/.gitignore @@ -0,0 +1,15 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts +./artifacts +./cache +./typechain + +deployments \ No newline at end of file diff --git a/packages/dependency-operator-filter/.prettierignore b/packages/dependency-operator-filter/.prettierignore new file mode 100644 index 0000000000..a77e23ebbf --- /dev/null +++ b/packages/dependency-operator-filter/.prettierignore @@ -0,0 +1,16 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts + +# generated docs +generated-markups + +# editors +.idea diff --git a/packages/dependency-operator-filter/.prettierrc.js b/packages/dependency-operator-filter/.prettierrc.js new file mode 100644 index 0000000000..60dbb58db3 --- /dev/null +++ b/packages/dependency-operator-filter/.prettierrc.js @@ -0,0 +1,15 @@ +module.exports = { + singleQuote: true, + bracketSpacing: false, + plugins: ['prettier-plugin-solidity'], + overrides: [ + { + files: '*.sol', + options: { + printWidth: 120, + tabWidth: 4, + singleQuote: false, + }, + }, + ], +}; diff --git a/packages/dependency-operator-filter/.solcover.js b/packages/dependency-operator-filter/.solcover.js new file mode 100644 index 0000000000..f6c4e5445d --- /dev/null +++ b/packages/dependency-operator-filter/.solcover.js @@ -0,0 +1,7 @@ +module.exports = { + mocha: { + grep: '@skip-on-coverage', // Find everything with this tag + invert: true, // Run the grep's inverse set. + }, + skipFiles: ['/mock'], +}; diff --git a/packages/dependency-operator-filter/.solhint.json b/packages/dependency-operator-filter/.solhint.json new file mode 100644 index 0000000000..d722fc1342 --- /dev/null +++ b/packages/dependency-operator-filter/.solhint.json @@ -0,0 +1,15 @@ +{ + "extends": "solhint:recommended", + "plugins": ["prettier"], + "rules": { + "prettier/prettier": [ + "error", + { + "endOfLine": "auto" + } + ], + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["error", {"ignoreConstructors": true}], + "reason-string": ["warn", {"maxLength": 64}] + } +} diff --git a/packages/dependency-operator-filter/.solhintignore b/packages/dependency-operator-filter/.solhintignore new file mode 100644 index 0000000000..d28fc94993 --- /dev/null +++ b/packages/dependency-operator-filter/.solhintignore @@ -0,0 +1 @@ +contracts/mock diff --git a/packages/dependency-operator-filter/README.md b/packages/dependency-operator-filter/README.md new file mode 100644 index 0000000000..ac1c2357e4 --- /dev/null +++ b/packages/dependency-operator-filter/README.md @@ -0,0 +1,68 @@ +# + +The Sandbox's operator-filter dependency package, for use by The Sandbox's token contracts. +Based on OpenSea's operator-filter. +This is a dependency package, and the smart contracts inside use floating pragma. + +## Running the project locally + +Install dependencies with `yarn` + +Testing: Use `yarn test` inside `packages/` to run tests locally inside this package + +For testing from root (with workspace feature) use: `yarn workspace @sandbox-smart-contracts/ test` + +Coverage: Run `yarn coverage` + +Formatting: Run `yarn prettier` to check and `yarn prettier:fix` to fix formatting errors + +Linting: Run `yarn lint` to check and `yarn lint:fix` to fix static analysis errors + +## Package structure and minimum standards + +#### A NOTE ON DEPENDENCIES + +1. Add whatever dependencies you like inside your package; this template is for hardhat usage. OpenZeppelin contracts + are highly recommended and should be installed as a dev dependency +2. For most Pull Requests there should be minimum changes to `yarn.lock` at root level +3. Changes to root-level dependencies are permissible, however they should not be downgraded +4. Take care to run `yarn` before pushing your changes +5. You shouldn't need to install dotenv since you won't be deploying inside this package (see below) + +#### UNIT TESTING + +1. Unit tests are to be added in `packages//test` +2. Coverage must meet minimum requirements for CI to pass +3. `getSigners` return an array of addresses, the first one is the default `deployer` for contracts, under no + circumstances should tests be written as `deployer` +4. It's permissible to create mock contracts at `packages//contracts/mock` e.g. for third-party contracts +5. Tests must not rely on any deploy scripts from the `deploy` package; your contracts must be deployed inside the test + fixture. See `test/fixtures.ts` + +# Deployment + +Each package must unit-test the contracts by running everything inside the `hardhat node`. Deployment to "real" +networks, configuration of our environment and integration tests must be done inside the `deploy` package. + +The `deploy` package only imports `.sol` files. The idea is to recompile everything inside it and manage the entire +deploy strategy from one place. + +1. Your deploy scripts should not be included inside `packages/`: deploy scripts live inside `packages/deploy/` +2. The `deploy` package doesn't use the hardhat config file from the specific package. Instead, it + uses `packages/deploy/hardhat.config.ts` +3. You will need to review `packages/deploy/hardhat.config.ts` and update it as needed for any new namedAccounts you + added to your package +4. When it comes to deploy time, it is preferred to include deploy scripts and end-to-end tests as a separate PR +5. The named accounts inside the `deploy` package must use the "real-life" values +6. Refer to the readme at `packages/deploy` to learn more about importing your package + +#### INTEGRATION TESTING + +1. End-to-end tests live at `packages/deploy/` +2. You must add end-to-end tests ahead of deploying your package. Importantly, these tests should verify deployment and + initialization configuration + +# A NOTE ON MAKING PULL REQUESTS + +1. Follow the PR template checklist +2. Your PR will not be approved if the above criteria are not met diff --git a/packages/dependency-operator-filter/contracts/OperatorFilterRegistrant.md b/packages/dependency-operator-filter/contracts/OperatorFilterRegistrant.md new file mode 100644 index 0000000000..020a8fe519 --- /dev/null +++ b/packages/dependency-operator-filter/contracts/OperatorFilterRegistrant.md @@ -0,0 +1,29 @@ +# OperatorFilterRegistry + +OpenSea in an attempt to regularize market places and creator earnings deployed a registry(https://github.com/ProjectOpenSea/operator-filter-registry) and asked NFT token contract to add filter logic(https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterer.sol). + +These filter has two modifier +1st : onlyAllowedOperator +2nd : onlyAllowedOperatorApproval + +These modifiers are added to to the transfer functions(onlyAllowedOperator) and approval function(onlyAllowedOperatorApproval) such that the when not an owner tried to transfer a Token(ex: Marketplace) or owner approves an operator(ex : Marketplace) they would be filtered on the OperatorFilterRegistry. + +If the operator or the token transfer is not approved by the registry the transaction would be reverted. + +On OperatorFilterRegistry a contract owner or the contract can register and maintain there own blacklist or subscribe to other blacklists but that blacklist should contain the default marketplaces blacklisted by OpenSea. + +# OperatorFiltererRegistrant + +The OperatorFiltererRegistrant contract is made to be registered on the OperatorFilterRegistry and copy the default blacklist of the OpenSea. This contract would then be subscribed by the contract such as AssetERC721 and AssetERC1155. + +The OperatorFiltererRegistrant would be the subscription for our token contracts on a layer(layer-1 : Ethereum , layer-2: Polygon), such that when a address is added or removed from OperatorFiltererRegistrant's blacklist it would be come in affect for each contact which subscribe to the OperatorFiltererRegistrant's blacklist. + +# Intended usage + +The OperatorFiltererRegistrant is so that sandbox will have a common blacklist that would be utilized by every Token contract on a layer. This would create a single list that would be subscribed by each contract to provide uniformity to which market places sandbox wants to blacklist. This would also provide a focal point to remove and add market places such that it would be applicable to every contract that subscribe to it. + +# Implementation + +We didn't use the npm package as its solidity pragma(solidity version) doesn't match the one we have for our Asset contracts and updating our solidity version for Assets would have been to time consuming. + +You won't find OperatorFilterRegistrant in the npm package as this contract is our implementation. diff --git a/packages/dependency-operator-filter/contracts/OperatorFilterSubscription.sol b/packages/dependency-operator-filter/contracts/OperatorFilterSubscription.sol new file mode 100644 index 0000000000..f5f41c7def --- /dev/null +++ b/packages/dependency-operator-filter/contracts/OperatorFilterSubscription.sol @@ -0,0 +1,23 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IOperatorFilterRegistry} from "./interfaces/IOperatorFilterRegistry.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +/// @title OperatorFilterSubription +/// @author The Sandbox +/// @notice This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on OpenSea operator filter registry +contract OperatorFilterSubscription is Ownable { + address public constant DEFAULT_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; + + // solhint-disable-next-line const-name-snakecase + IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY = + IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); + + constructor() Ownable() { + // Subscribe and copy the entries of the Default subscription list of OpenSea. + if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) { + OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION); + } + } +} diff --git a/packages/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol b/packages/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol new file mode 100644 index 0000000000..526e18846a --- /dev/null +++ b/packages/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol @@ -0,0 +1,91 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {IOperatorFilterRegistry} from "./interfaces/IOperatorFilterRegistry.sol"; +import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; + +///@title OperatorFiltererUpgradeable +///@author The Sandbox +///@notice This contract would subscribe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's address could be set using a setter which could be implemented in inheriting contract +abstract contract OperatorFiltererUpgradeable is Initializable, ContextUpgradeable { + event OperatorFilterRegistrySet(address indexed registry); + + IOperatorFilterRegistry private operatorFilterRegistry; + + // solhint-disable-next-line func-name-mixedcase + function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing { + operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry + // If an inheriting token contract is deployed to a network without the registry deployed, the modifier + // will not revert, but the contract will need to be registered with the registry once it is deployed in + // order for the modifier to filter addresses. + _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe); + } + + function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal { + if (address(operatorFilterRegistry).code.length > 0) { + if (!operatorFilterRegistry.isRegistered(address(this))) { + if (subscribe) { + operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); + } else { + if (subscriptionOrRegistrantToCopy != address(0)) { + operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); + } else { + operatorFilterRegistry.register(address(this)); + } + } + } + } + } + + modifier onlyAllowedOperator(address from) virtual { + // Check registry code length to facilitate testing in environments without a deployed registry. + if (address(operatorFilterRegistry).code.length > 0) { + // Allow spending tokens from addresses with balance + // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred + // from an EOA. + if (from == _msgSender()) { + _; + return; + } + if (!operatorFilterRegistry.isOperatorAllowed(address(this), _msgSender())) { + revert("Operator Not Allowed"); + } + } + _; + } + + modifier onlyAllowedOperatorApproval(address operator) virtual { + // Check registry code length to facilitate testing in environments without a deployed registry. + if (address(operatorFilterRegistry).code.length > 0) { + if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) { + revert("Operator Not Allowed"); + } + } + _; + } + + /// @notice returns the operator filter registry. + /// @return operatorFilterRegistryAddress address of operator filter registry contract. + function getOperatorFilterRegistry() external view returns (IOperatorFilterRegistry operatorFilterRegistryAddress) { + return _getOperatorFilterRegistry(); + } + + /// @notice internal method to set the operator filter registry + /// @param registry address the registry. + function _setOperatorFilterRegistry(address registry) internal { + operatorFilterRegistry = IOperatorFilterRegistry(registry); + emit OperatorFilterRegistrySet(registry); + } + + /// @notice internal method to get the operator filter registry. + function _getOperatorFilterRegistry() + internal + view + returns (IOperatorFilterRegistry operatorFilterRegistryAddress) + { + return operatorFilterRegistry; + } + + uint256[49] private __gap; +} diff --git a/packages/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol b/packages/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol new file mode 100644 index 0000000000..769597d08f --- /dev/null +++ b/packages/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IOperatorFilterRegistry +/// @notice Interface for managing operators and filtering. +interface IOperatorFilterRegistry { + ///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns + /// true if supplied registrant address is not registered. + function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed); + + ///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. + function register(address registrant) external; + + ///@notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. + function registerAndSubscribe(address registrant, address subscription) external; + + ///@notice Registers an address with the registry and copies the filtered operators and codeHashes from another + /// address without subscribing. + function registerAndCopyEntries(address registrant, address registrantToCopy) external; + + ///@notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. + /// Note that this does not remove any filtered addresses or codeHashes. + /// Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. + function unregister(address addr) external; + + ///@notice Update an operator address for a registered address - when filtered is true, the operator is filtered. + function updateOperator( + address registrant, + address operator, + bool filtered + ) external; + + ///@notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. + function updateOperators( + address registrant, + address[] calldata operators, + bool filtered + ) external; + + ///@notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. + function updateCodeHash( + address registrant, + bytes32 codehash, + bool filtered + ) external; + + ///@notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. + function updateCodeHashes( + address registrant, + bytes32[] calldata codeHashes, + bool filtered + ) external; + + ///@notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous + /// subscription if present. + /// Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, + /// subscriptions will not be forwarded. Instead the former subscription's existing entries will still be + /// used. + function subscribe(address registrant, address registrantToSubscribe) external; + + ///@notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. + function unsubscribe(address registrant, bool copyExistingEntries) external; + + ///@notice Get the subscription address of a given registrant, if any. + function subscriptionOf(address addr) external returns (address registrant); + + ///@notice Get the set of addresses subscribed to a given registrant. + /// Note that order is not guaranteed as updates are made. + function subscribers(address registrant) external returns (address[] memory subscribersList); + + ///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. + /// Note that order is not guaranteed as updates are made. + function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress); + + ///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. + function copyEntriesOf(address registrant, address registrantToCopy) external; + + ///@notice Returns true if operator is filtered by a given address or its subscription. + function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered); + + ///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription. + function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered); + + ///@notice Returns true if a codeHash is filtered by a given address or its subscription. + function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered); + + ///@notice Returns a list of filtered operators for a given address or its subscription. + function filteredOperators(address addr) external returns (address[] memory operatorList); + + ///@notice Returns the set of filtered codeHashes for a given address or its subscription. + /// Note that order is not guaranteed as updates are made. + function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList); + + ///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or + /// its subscription. + /// Note that order is not guaranteed as updates are made. + function filteredOperatorAt(address registrant, uint256 index) external returns (address operator); + + ///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or + /// its subscription. + /// Note that order is not guaranteed as updates are made. + function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash); + + ///@notice Returns true if an address has registered + function isRegistered(address addr) external returns (bool registered); + + ///@dev Convenience method to compute the code hash of an arbitrary contract + function codeHashOf(address addr) external returns (bytes32 codeHash); +} diff --git a/packages/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol new file mode 100644 index 0000000000..e0313f9524 --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol @@ -0,0 +1,72 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol"; +import {ERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol"; +import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +contract MockERC1155MarketPlace1 is ERC1155Receiver, ERC721Holder { + bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0; + bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61; + bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81; + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param amount amount of token transfered. + /// @param data aditional data accompanying the transfer. + function transferTokenForERC1155( + address asset, + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param amounts amount of each token type transfered. + /// @param data aditional data accompanying the transfer. + function batchTransferTokenERC1155( + address asset, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data); + } + + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_RECEIVED; + } + + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_BATCH_RECEIVED; + } + + function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) { + interfaceId = super.supportsInterface(_interfaceId); + return interfaceId; + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol new file mode 100644 index 0000000000..9e6d09a25d --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol @@ -0,0 +1,72 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol"; +import {ERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol"; +import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +contract MockERC1155MarketPlace2 is ERC1155Receiver, ERC721Holder { + bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0; + bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61; + bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81; + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param amount amount of token transfered. + /// @param data aditional data accompanying the transfer. + function transferTokenForERC1155( + address asset, + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param amounts amount of each token type transfered. + /// @param data aditional data accompanying the transfer. + function batchTransferTokenERC1155( + address asset, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data); + } + + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_RECEIVED; + } + + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_BATCH_RECEIVED; + } + + function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) { + interfaceId = super.supportsInterface(_interfaceId); + return interfaceId; + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol new file mode 100644 index 0000000000..bd780e66ca --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol @@ -0,0 +1,72 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol"; +import {ERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol"; +import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +contract MockERC1155MarketPlace3 is ERC1155Receiver, ERC721Holder { + bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0; + bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61; + bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81; + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param amount amount of token transfered. + /// @param data aditional data accompanying the transfer. + function transferTokenForERC1155( + address asset, + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param amounts amount of each token type transfered. + /// @param data aditional data accompanying the transfer. + function batchTransferTokenERC1155( + address asset, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data); + } + + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_RECEIVED; + } + + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_BATCH_RECEIVED; + } + + function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) { + interfaceId = super.supportsInterface(_interfaceId); + return interfaceId; + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol new file mode 100644 index 0000000000..1119e0dbb4 --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol @@ -0,0 +1,72 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol"; +import {ERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol"; +import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +contract MockERC1155MarketPlace4 is ERC1155Receiver, ERC721Holder { + bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0; + bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61; + bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81; + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param amount amount of token transfered. + /// @param data aditional data accompanying the transfer. + function transferTokenForERC1155( + address asset, + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @param asset the contract address on which the token transfer will take place + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param amounts amount of each token type transfered. + /// @param data aditional data accompanying the transfer. + function batchTransferTokenERC1155( + address asset, + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) external { + IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data); + } + + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_RECEIVED; + } + + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) external pure returns (bytes4) { + return ERC1155_BATCH_RECEIVED; + } + + function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) { + interfaceId = super.supportsInterface(_interfaceId); + return interfaceId; + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol b/packages/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol new file mode 100644 index 0000000000..bfcb5019e3 --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol @@ -0,0 +1,565 @@ +// SPDX-License-Identifier: MIT +// solhint-disable code-complexity +pragma solidity ^0.8.0; + +import {IOperatorFilterRegistry} from "operator-filter-registry/src/IOperatorFilterRegistry.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { + OperatorFilterRegistryErrorsAndEvents +} from "operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol"; + +/** + * @title MockOperatorFilterRegistry + * @notice Made based on the OperatorFilterRegistry of OpenSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol + * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be + * * restricted according to the isOperatorAllowed function. + */ +contract MockOperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents { + using EnumerableSet for EnumerableSet.AddressSet; + using EnumerableSet for EnumerableSet.Bytes32Set; + + /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052) + /// Note that this will also be a smart contract's codehash when making calls from its constructor. + bytes32 internal constant EOA_CODEHASH = keccak256(""); + + mapping(address => EnumerableSet.AddressSet) private _filteredOperators; + mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes; + mapping(address => address) private _registrations; + mapping(address => EnumerableSet.AddressSet) private _subscribers; + + constructor(address _defaultSubscription, address[] memory _blacklistedAddresses) { + _registrations[_defaultSubscription] = _defaultSubscription; + EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[_defaultSubscription]; + EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[_defaultSubscription]; + for (uint256 i; i < _blacklistedAddresses.length; i++) { + filteredOperatorsRef.add(_blacklistedAddresses[i]); + bytes32 codeHash = _blacklistedAddresses[i].codehash; + filteredCodeHashesRef.add(codeHash); + } + } + + /** + * @notice Restricts method caller to the address or EIP-173 "owner()" + */ + modifier onlyAddressOrOwner(address addr) { + if (msg.sender != addr) { + try Ownable(addr).owner() returns (address owner) { + if (msg.sender != owner) { + revert OnlyAddressOrOwner(); + } + } catch (bytes memory reason) { + if (reason.length == 0) { + revert NotOwnable(); + } else { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, reason), mload(reason)) + } + } + } + } + _; + } + + /** + * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns + * true if supplied registrant address is not registered. + * Note that this method will *revert* if an operator or its codehash is filtered with an error that is + * more informational than a false boolean, so smart contracts that query this method for informational + * purposes will need to wrap in a try/catch or perform a low-level staticcall in order to handle the case + * that an operator is filtered. + */ + function isOperatorAllowed(address registrant, address operator) external view returns (bool) { + address registration = _registrations[registrant]; + if (registration != address(0)) { + EnumerableSet.AddressSet storage filteredOperatorsRef; + EnumerableSet.Bytes32Set storage filteredCodeHashesRef; + + filteredOperatorsRef = _filteredOperators[registration]; + filteredCodeHashesRef = _filteredCodeHashes[registration]; + + if (filteredOperatorsRef.contains(operator)) { + revert AddressFiltered(operator); + } + if (operator.code.length > 0) { + bytes32 codeHash = operator.codehash; + if (filteredCodeHashesRef.contains(codeHash)) { + revert CodeHashFiltered(operator, codeHash); + } + } + } + return true; + } + + ////////////////// + // AUTH METHODS // + ////////////////// + + /** + * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. + */ + function register(address registrant) external onlyAddressOrOwner(registrant) { + if (_registrations[registrant] != address(0)) { + revert AlreadyRegistered(); + } + _registrations[registrant] = registrant; + emit RegistrationUpdated(registrant, true); + } + + /** + * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. + * Note that this does not remove any filtered addresses or codeHashes. + * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. + */ + function unregister(address registrant) external onlyAddressOrOwner(registrant) { + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration != registrant) { + _subscribers[registration].remove(registrant); + emit SubscriptionUpdated(registrant, registration, false); + } + _registrations[registrant] = address(0); + emit RegistrationUpdated(registrant, false); + } + + /** + * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. + */ + function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) { + address registration = _registrations[registrant]; + if (registration != address(0)) { + revert AlreadyRegistered(); + } + if (registrant == subscription) { + revert CannotSubscribeToSelf(); + } + address subscriptionRegistration = _registrations[subscription]; + if (subscriptionRegistration == address(0)) { + revert NotRegistered(subscription); + } + if (subscriptionRegistration != subscription) { + revert CannotSubscribeToRegistrantWithSubscription(subscription); + } + + _registrations[registrant] = subscription; + _subscribers[subscription].add(registrant); + emit RegistrationUpdated(registrant, true); + emit SubscriptionUpdated(registrant, subscription, true); + } + + /** + * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another + * address without subscribing. + */ + function registerAndCopyEntries(address registrant, address registrantToCopy) + external + onlyAddressOrOwner(registrant) + { + if (registrantToCopy == registrant) { + revert CannotCopyFromSelf(); + } + address registration = _registrations[registrant]; + if (registration != address(0)) { + revert AlreadyRegistered(); + } + address registrantRegistration = _registrations[registrantToCopy]; + if (registrantRegistration == address(0)) { + revert NotRegistered(registrantToCopy); + } + _registrations[registrant] = registrant; + emit RegistrationUpdated(registrant, true); + _copyEntries(registrant, registrantToCopy); + } + + /** + * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. + */ + function updateOperator( + address registrant, + address operator, + bool filtered + ) external onlyAddressOrOwner(registrant) { + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration != registrant) { + revert CannotUpdateWhileSubscribed(registration); + } + EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; + + if (!filtered) { + bool removed = filteredOperatorsRef.remove(operator); + if (!removed) { + revert AddressNotFiltered(operator); + } + } else { + bool added = filteredOperatorsRef.add(operator); + if (!added) { + revert AddressAlreadyFiltered(operator); + } + } + emit OperatorUpdated(registrant, operator, filtered); + } + + /** + * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. + * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior, + * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any + * un-initialized account. Since un-initialized accounts have no code, the registry will not validate + * that an un-initalized account's codeHash is not filtered. By the time an account is able to + * act as an operator (an account is initialized or a smart contract exclusively in the context of its + * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered. + */ + function updateCodeHash( + address registrant, + bytes32 codeHash, + bool filtered + ) external onlyAddressOrOwner(registrant) { + if (codeHash == EOA_CODEHASH) { + revert CannotFilterEOAs(); + } + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration != registrant) { + revert CannotUpdateWhileSubscribed(registration); + } + EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; + + if (!filtered) { + bool removed = filteredCodeHashesRef.remove(codeHash); + if (!removed) { + revert CodeHashNotFiltered(codeHash); + } + } else { + bool added = filteredCodeHashesRef.add(codeHash); + if (!added) { + revert CodeHashAlreadyFiltered(codeHash); + } + } + emit CodeHashUpdated(registrant, codeHash, filtered); + } + + /** + * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. + */ + function updateOperators( + address registrant, + address[] calldata operators, + bool filtered + ) external onlyAddressOrOwner(registrant) { + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration != registrant) { + revert CannotUpdateWhileSubscribed(registration); + } + EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; + uint256 operatorsLength = operators.length; + if (!filtered) { + for (uint256 i = 0; i < operatorsLength; ) { + address operator = operators[i]; + bool removed = filteredOperatorsRef.remove(operator); + if (!removed) { + revert AddressNotFiltered(operator); + } + unchecked {++i;} + } + } else { + for (uint256 i = 0; i < operatorsLength; ) { + address operator = operators[i]; + bool added = filteredOperatorsRef.add(operator); + if (!added) { + revert AddressAlreadyFiltered(operator); + } + unchecked {++i;} + } + } + emit OperatorsUpdated(registrant, operators, filtered); + } + + /** + * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. + * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior, + * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any + * un-initialized account. Since un-initialized accounts have no code, the registry will not validate + * that an un-initalized account's codeHash is not filtered. By the time an account is able to + * act as an operator (an account is initialized or a smart contract exclusively in the context of its + * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered. + */ + function updateCodeHashes( + address registrant, + bytes32[] calldata codeHashes, + bool filtered + ) external onlyAddressOrOwner(registrant) { + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration != registrant) { + revert CannotUpdateWhileSubscribed(registration); + } + EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; + uint256 codeHashesLength = codeHashes.length; + if (!filtered) { + for (uint256 i = 0; i < codeHashesLength; ) { + bytes32 codeHash = codeHashes[i]; + bool removed = filteredCodeHashesRef.remove(codeHash); + if (!removed) { + revert CodeHashNotFiltered(codeHash); + } + unchecked {++i;} + } + } else { + for (uint256 i = 0; i < codeHashesLength; ) { + bytes32 codeHash = codeHashes[i]; + if (codeHash == EOA_CODEHASH) { + revert CannotFilterEOAs(); + } + bool added = filteredCodeHashesRef.add(codeHash); + if (!added) { + revert CodeHashAlreadyFiltered(codeHash); + } + unchecked {++i;} + } + } + emit CodeHashesUpdated(registrant, codeHashes, filtered); + } + + /** + * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous + * subscription if present. + * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, + * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be + * used. + */ + function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) { + if (registrant == newSubscription) { + revert CannotSubscribeToSelf(); + } + if (newSubscription == address(0)) { + revert CannotSubscribeToZeroAddress(); + } + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration == newSubscription) { + revert AlreadySubscribed(newSubscription); + } + address newSubscriptionRegistration = _registrations[newSubscription]; + if (newSubscriptionRegistration == address(0)) { + revert NotRegistered(newSubscription); + } + if (newSubscriptionRegistration != newSubscription) { + revert CannotSubscribeToRegistrantWithSubscription(newSubscription); + } + + if (registration != registrant) { + _subscribers[registration].remove(registrant); + emit SubscriptionUpdated(registrant, registration, false); + } + _registrations[registrant] = newSubscription; + _subscribers[newSubscription].add(registrant); + emit SubscriptionUpdated(registrant, newSubscription, true); + } + + /** + * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. + */ + function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) { + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration == registrant) { + revert NotSubscribed(); + } + _subscribers[registration].remove(registrant); + _registrations[registrant] = registrant; + emit SubscriptionUpdated(registrant, registration, false); + if (copyExistingEntries) { + _copyEntries(registrant, registration); + } + } + + /** + * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. + */ + function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { + if (registrant == registrantToCopy) { + revert CannotCopyFromSelf(); + } + address registration = _registrations[registrant]; + if (registration == address(0)) { + revert NotRegistered(registrant); + } + if (registration != registrant) { + revert CannotUpdateWhileSubscribed(registration); + } + address registrantRegistration = _registrations[registrantToCopy]; + if (registrantRegistration == address(0)) { + revert NotRegistered(registrantToCopy); + } + _copyEntries(registrant, registrantToCopy); + } + + /// @dev helper to copy entries from registrantToCopy to registrant and emit events + function _copyEntries(address registrant, address registrantToCopy) private { + EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy]; + EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy]; + uint256 filteredOperatorsLength = filteredOperatorsRef.length(); + uint256 filteredCodeHashesLength = filteredCodeHashesRef.length(); + for (uint256 i = 0; i < filteredOperatorsLength; ) { + address operator = filteredOperatorsRef.at(i); + bool added = _filteredOperators[registrant].add(operator); + if (added) { + emit OperatorUpdated(registrant, operator, true); + } + unchecked {++i;} + } + for (uint256 i = 0; i < filteredCodeHashesLength; ) { + bytes32 codehash = filteredCodeHashesRef.at(i); + bool added = _filteredCodeHashes[registrant].add(codehash); + if (added) { + emit CodeHashUpdated(registrant, codehash, true); + } + unchecked {++i;} + } + } + + ////////////////// + // VIEW METHODS // + ////////////////// + + /** + * @notice Get the subscription address of a given registrant, if any. + */ + function subscriptionOf(address registrant) external view returns (address subscription) { + subscription = _registrations[registrant]; + if (subscription == address(0)) { + revert NotRegistered(registrant); + } else if (subscription == registrant) { + subscription = address(0); + } + } + + /** + * @notice Get the set of addresses subscribed to a given registrant. + * Note that order is not guaranteed as updates are made. + */ + function subscribers(address registrant) external view returns (address[] memory) { + return _subscribers[registrant].values(); + } + + /** + * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. + * Note that order is not guaranteed as updates are made. + */ + function subscriberAt(address registrant, uint256 index) external view returns (address) { + return _subscribers[registrant].at(index); + } + + /** + * @notice Returns true if operator is filtered by a given address or its subscription. + */ + function isOperatorFiltered(address registrant, address operator) external view returns (bool) { + address registration = _registrations[registrant]; + if (registration != registrant) { + return _filteredOperators[registration].contains(operator); + } + return _filteredOperators[registrant].contains(operator); + } + + /** + * @notice Returns true if a codeHash is filtered by a given address or its subscription. + */ + function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) { + address registration = _registrations[registrant]; + if (registration != registrant) { + return _filteredCodeHashes[registration].contains(codeHash); + } + return _filteredCodeHashes[registrant].contains(codeHash); + } + + /** + * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. + */ + function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) { + bytes32 codeHash = operatorWithCode.codehash; + address registration = _registrations[registrant]; + if (registration != registrant) { + return _filteredCodeHashes[registration].contains(codeHash); + } + return _filteredCodeHashes[registrant].contains(codeHash); + } + + /** + * @notice Returns true if an address has registered + */ + function isRegistered(address registrant) external view returns (bool) { + return _registrations[registrant] != address(0); + } + + /** + * @notice Returns a list of filtered operators for a given address or its subscription. + */ + function filteredOperators(address registrant) external view returns (address[] memory) { + address registration = _registrations[registrant]; + if (registration != registrant) { + return _filteredOperators[registration].values(); + } + return _filteredOperators[registrant].values(); + } + + /** + * @notice Returns the set of filtered codeHashes for a given address or its subscription. + * Note that order is not guaranteed as updates are made. + */ + function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) { + address registration = _registrations[registrant]; + if (registration != registrant) { + return _filteredCodeHashes[registration].values(); + } + return _filteredCodeHashes[registrant].values(); + } + + /** + * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or + * its subscription. + * Note that order is not guaranteed as updates are made. + */ + function filteredOperatorAt(address registrant, uint256 index) external view returns (address) { + address registration = _registrations[registrant]; + if (registration != registrant) { + return _filteredOperators[registration].at(index); + } + return _filteredOperators[registrant].at(index); + } + + /** + * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or + * its subscription. + * Note that order is not guaranteed as updates are made. + */ + function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) { + address registration = _registrations[registrant]; + if (registration != registrant) { + return _filteredCodeHashes[registration].at(index); + } + return _filteredCodeHashes[registrant].at(index); + } + + /** + * @dev Convenience method to compute the code hash of an arbitrary contract + */ + function codeHashOf(address a) external view returns (bytes32) { + return a.codehash; + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol b/packages/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol new file mode 100644 index 0000000000..ff1190259e --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IOperatorFilterRegistry} from "operator-filter-registry/src/IOperatorFilterRegistry.sol"; +import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; + +/** + * @title OwnedRegistrant + * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries, + * to facilitate a subscription whose ownership can be transferred. + */ + +contract MockOperatorFilterSubscription is Ownable2Step { + address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); + + /// @dev The constructor that is called when the contract is being deployed. + /// @dev This contract is based on OpenSea's OwnedRegistrant. + /// @dev The param _localRegistry has been added to the constructor to enable local testing. + constructor(address _owner, address _localRegistry) { + IOperatorFilterRegistry(_localRegistry).registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION); + transferOwnership(_owner); + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/MockTrustedForwarder.sol b/packages/dependency-operator-filter/contracts/mock/MockTrustedForwarder.sol new file mode 100644 index 0000000000..7048aa7bac --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/MockTrustedForwarder.sol @@ -0,0 +1,4 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {MockTrustedForwarder} from "@sandbox-smart-contracts/dependency-metatx/contracts/test/MockTrustedForwarder.sol"; diff --git a/packages/dependency-operator-filter/contracts/mock/TestERC1155.sol b/packages/dependency-operator-filter/contracts/mock/TestERC1155.sol new file mode 100644 index 0000000000..25189616bf --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/TestERC1155.sol @@ -0,0 +1,116 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + ERC1155Upgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; +import {OperatorFiltererUpgradeable} from "../OperatorFiltererUpgradeable.sol"; + +import {IOperatorFilterRegistry} from "../interfaces/IOperatorFilterRegistry.sol"; + +contract TestERC1155 is ERC1155Upgradeable, OperatorFiltererUpgradeable, ERC2771HandlerUpgradeable { + function initialize(string memory uri_, address trustedForwarder) external initializer { + __ERC1155_init(uri_); + __ERC2771Handler_init(trustedForwarder); + } + + /// @notice sets registry and subscribe to subscription + /// @param registry address of registry + /// @param subscription address to subscribe + function setRegistryAndSubscribe(address registry, address subscription) external { + _setOperatorFilterRegistry(registry); + IOperatorFilterRegistry(registry).registerAndSubscribe(address(this), subscription); + } + + /// @notice Mint new tokens with out minter role + /// @param to The address of the recipient + /// @param id The id of the token to mint + /// @param amount The amount of the token to mint + function mintWithoutMinterRole( + address to, + uint256 id, + uint256 amount + ) external { + _mint(to, id, amount, ""); + } + + /// @notice set approval for token transfer without filtering + /// @param operator operator to be approved + /// @param approved bool value for giving (true) and canceling (false) approval + function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual { + _setApprovalForAll(_msgSender(), operator, approved); + } + + function msgData() external view returns (bytes memory) { + return _msgData(); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @dev call data should be optimized to order ids so packedBalance can be used efficiently. + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param amounts amount of each token type transfered. + /// @param data aditional data accompanying the transfer. + function safeBatchTransferFrom( + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) public virtual override onlyAllowedOperator(from) { + super.safeBatchTransferFrom(from, to, ids, amounts, data); + } + + /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens. + /// @param operator address which will be granted rights to transfer all tokens of the caller. + /// @param approved whether to approve or revoke + function setApprovalForAll(address operator, bool approved) + public + virtual + override + onlyAllowedOperatorApproval(operator) + { + super.setApprovalForAll(operator, approved); + } + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param amount amount of token transfered. + /// @param data aditional data accompanying the transfer. + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) public virtual override onlyAllowedOperator(from) { + super.safeTransferFrom(from, to, id, amount, data); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/TestERC721.sol b/packages/dependency-operator-filter/contracts/mock/TestERC721.sol new file mode 100644 index 0000000000..f2a81e6fd0 --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/TestERC721.sol @@ -0,0 +1,92 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + ERC721Upgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; +import {OperatorFiltererUpgradeable} from "../OperatorFiltererUpgradeable.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; +import {IOperatorFilterRegistry} from "../interfaces/IOperatorFilterRegistry.sol"; + +contract TestERC721 is ERC721Upgradeable, OperatorFiltererUpgradeable, ERC2771HandlerUpgradeable { + function initialize( + string memory name_, + string memory symbol_, + address trustedForwarder + ) external initializer() { + __ERC721_init(name_, symbol_); + __ERC2771Handler_init(trustedForwarder); + } + + /// @notice sets registry and subscribe to subscription + /// @param registry address of registry + /// @param subscription address to subscribe + function setRegistryAndSubscribe(address registry, address subscription) external { + _setOperatorFilterRegistry(registry); + IOperatorFilterRegistry(registry).registerAndSubscribe(address(this), subscription); + } + + /// @notice Mint new tokens with out minter role + /// @param to The address of the recipient + /// @param id The id of the token to mint + function mintWithoutMinterRole(address to, uint256 id) external { + _mint(to, id); + } + + /// @notice set approval for asset transfer without filtering + /// @param operator operator to be approved + /// @param approved bool value for giving (true) and canceling (false) approval + function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual { + _setApprovalForAll(_msgSender(), operator, approved); + } + + function msgData() external view returns (bytes memory) { + return _msgData(); + } + + /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens. + /// @param operator address which will be granted rights to transfer all tokens of the caller. + /// @param approved whether to approve or revoke + function setApprovalForAll(address operator, bool approved) + public + virtual + override + onlyAllowedOperatorApproval(operator) + { + _setApprovalForAll(_msgSender(), operator, approved); + } + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + function safeTransferFrom( + address from, + address to, + uint256 id + ) public virtual override onlyAllowedOperator(from) { + super.safeTransferFrom(from, to, id); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } +} diff --git a/packages/dependency-operator-filter/contracts/mock/UnregisteredToken.sol b/packages/dependency-operator-filter/contracts/mock/UnregisteredToken.sol new file mode 100644 index 0000000000..e93f814e28 --- /dev/null +++ b/packages/dependency-operator-filter/contracts/mock/UnregisteredToken.sol @@ -0,0 +1,134 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import { + ERC1155Upgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {OperatorFiltererUpgradeable} from "../OperatorFiltererUpgradeable.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; +import {IOperatorFilterRegistry} from "../interfaces/IOperatorFilterRegistry.sol"; + +contract UnregisteredToken is ERC1155Upgradeable, OperatorFiltererUpgradeable, ERC2771HandlerUpgradeable { + function initialize( + string memory uri_, + address subscription, + bool subscribe, + address trustedForwarder + ) external initializer() { + __ERC1155_init(uri_); + __OperatorFilterer_init(subscription, subscribe); + __ERC2771Handler_init(trustedForwarder); + } + + /// @notice sets registry + /// @param registry address of registry + function setRegistry(address registry) external { + _setOperatorFilterRegistry(registry); + } + + /// @notice register contract + /// @param subscription the address of subscription + /// @param subscribe bool representing to suscribe or not. + function registerAndSubscribe(address subscription, bool subscribe) external { + _registerAndSubscribe(subscription, subscribe); + } + + /// @notice sets registry and subscribe to subscription + /// @param registry address of registry + /// @param subscription address to subscribe + function setRegistryAndSubscribe(address registry, address subscription) external { + _setOperatorFilterRegistry(registry); + IOperatorFilterRegistry(registry).registerAndSubscribe(address(this), subscription); + } + + /// @notice Mint new tokens with out minter role + /// @param to The address of the recipient + /// @param id The id of the token to mint + /// @param amount The amount of the token to mint + function mintWithoutMinterRole( + address to, + uint256 id, + uint256 amount + ) external { + _mint(to, id, amount, ""); + } + + /// @notice set approval for asset transfer without filtering + /// @param operator operator to be approved + /// @param approved bool value for giving (true) and canceling (false) approval + function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual { + _setApprovalForAll(_msgSender(), operator, approved); + } + + function msgData() external view returns (bytes memory) { + return _msgData(); + } + + /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call). + /// @dev call data should be optimized to order ids so packedBalance can be used efficiently. + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param ids ids of each token type transfered. + /// @param amounts amount of each token type transfered. + /// @param data aditional data accompanying the transfer. + function safeBatchTransferFrom( + address from, + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) public virtual override onlyAllowedOperator(from) { + super.safeBatchTransferFrom(from, to, ids, amounts, data); + } + + /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens. + /// @param operator address which will be granted rights to transfer all tokens of the caller. + /// @param approved whether to approve or revoke + function setApprovalForAll(address operator, bool approved) + public + virtual + override + onlyAllowedOperatorApproval(operator) + { + super.setApprovalForAll(operator, approved); + } + + /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call). + /// @param from address from which tokens are transfered. + /// @param to address to which the token will be transfered. + /// @param id the token type transfered. + /// @param amount amount of token transfered. + /// @param data aditional data accompanying the transfer. + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes memory data + ) public virtual override onlyAllowedOperator(from) { + super.safeTransferFrom(from, to, id, amount, data); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } +} diff --git a/packages/dependency-operator-filter/hardhat.config.ts b/packages/dependency-operator-filter/hardhat.config.ts new file mode 100644 index 0000000000..a62676034f --- /dev/null +++ b/packages/dependency-operator-filter/hardhat.config.ts @@ -0,0 +1,23 @@ +import '@nomicfoundation/hardhat-toolbox'; +import {HardhatUserConfig} from 'hardhat/config'; +import 'solidity-coverage'; +import '@openzeppelin/hardhat-upgrades'; + +const config: HardhatUserConfig = { + // solidity compiler version may be updated for new packages as required + // to ensure packages use up-to-date dependencies + solidity: { + compilers: [ + { + version: '0.8.18', + settings: { + optimizer: { + enabled: true, + runs: 2000, + }, + }, + }, + ], + }, +}; +export default config; diff --git a/packages/dependency-operator-filter/package.json b/packages/dependency-operator-filter/package.json new file mode 100644 index 0000000000..7f93fa82b2 --- /dev/null +++ b/packages/dependency-operator-filter/package.json @@ -0,0 +1,63 @@ +{ + "name": "@sandbox-smart-contracts/dependency-operator-filter", + "version": "0.0.1", + "description": "Implementation for OpenSea's operator filter", + "files": [ + "contracts" + ], + "scripts": { + "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && solhint --max-warnings 0 \"contracts/**/*.sol\"", + "lint:fix": "eslint --fix \"**/*.{js,ts}\" && solhint --fix \"contracts/**/*.sol\"", + "format": "prettier --check \"**/*.{ts,js,sol}\"", + "format:fix": "prettier --write \"**/*.{ts,js,sol}\"", + "test": "hardhat test", + "coverage": "hardhat coverage --testfiles 'test/*.ts''test/*.js'", + "hardhat": "hardhat", + "compile": "hardhat compile" + }, + "mocha": { + "require": "hardhat/register", + "timeout": 40000, + "_": [ + "test/**/*.ts" + ] + }, + "devDependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", + "@nomiclabs/hardhat-etherscan": "^3.1.7", + "@openzeppelin/contracts": "^4.9.0", + "@openzeppelin/contracts-upgradeable": "^4.9.0", + "@openzeppelin/hardhat-upgrades": "^1.28.0", + "@sandbox-smart-contracts/dependency-metatx": "*", + "@typechain/ethers-v5": "^10.2.1", + "@typechain/hardhat": "^6.1.6", + "@types/chai": "^4.3.5", + "@types/mocha": "^10.0.1", + "@types/node": "^20.1.2", + "@typescript-eslint/eslint-plugin": "^5.59.8", + "@typescript-eslint/parser": "^5.59.8", + "chai": "^4.3.7", + "dotenv": "^16.1.4", + "eslint": "^8.41.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-mocha": "^10.1.0", + "eslint-plugin-prettier": "^4.2.1", + "ethers": "^5.7.2", + "hardhat": "^2.14.1", + "hardhat-gas-reporter": "^1.0.9", + "operator-filter-registry": "^1.4.2", + "prettier": "^2.8.8", + "prettier-plugin-solidity": "1.0.0-beta.11", + "solhint": "^3.4.1", + "solhint-plugin-prettier": "^0.0.5", + "solidity-coverage": "^0.8.2", + "ts-node": "^10.9.1", + "typechain": "^8.1.1", + "typescript": "^5.0.4" + } +} diff --git a/packages/dependency-operator-filter/test/OperatorFilter.test.ts b/packages/dependency-operator-filter/test/OperatorFilter.test.ts new file mode 100644 index 0000000000..77fc11ea06 --- /dev/null +++ b/packages/dependency-operator-filter/test/OperatorFilter.test.ts @@ -0,0 +1,1527 @@ +import {expect} from 'chai'; +import {ethers} from 'hardhat'; +import {setupOperatorFilter} from './fixtures/testFixture'; +const zeroAddress = '0x0000000000000000000000000000000000000000'; + +describe('OperatorFilterer', function () { + describe('common contract subscription setup', function () { + it('should be registered', async function () { + const {operatorFilterRegistry, ERC1155} = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isRegistered(ERC1155.address) + ).to.be.equal(true); + }); + + it('should not be registered on operator filter registry if not set on the token', async function () { + const {operatorFilterRegistry, UnregisteredToken} = + await setupOperatorFilter(); + await UnregisteredToken.registerAndSubscribe(zeroAddress, false); + + expect( + await operatorFilterRegistry.isRegistered(UnregisteredToken.address) + ).to.be.equal(false); + }); + + it('should not be registered if registry is not deployed', async function () { + const {operatorFilterRegistry} = await setupOperatorFilter(); + + const OperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'OperatorFilterSubscription' + ); + + const operatorFilterSubscription = + await OperatorFilterSubscriptionFactory.deploy(); + expect( + await operatorFilterRegistry.isRegistered( + operatorFilterSubscription.address + ) + ).to.be.equal(false); + }); + + it('should not subscribe to operatorFilterSubscription if token is already registered', async function () { + const { + operatorFilterRegistry, + operatorFilterSubscription, + UnregisteredToken, + } = await setupOperatorFilter(); + await UnregisteredToken.setRegistry(operatorFilterRegistry.address); + await UnregisteredToken.registerAndSubscribe(zeroAddress, false); + await UnregisteredToken.registerAndSubscribe( + operatorFilterSubscription.address, + true + ); + + expect( + await operatorFilterRegistry.subscriptionOf(UnregisteredToken.address) + ).to.be.equal(zeroAddress); + }); + + it('should not subscribe to operatorFilterSubscription if is already registered', async function () { + const { + operatorFilterRegistry, + operatorFilterSubscription, + UnregisteredToken, + } = await setupOperatorFilter(); + await UnregisteredToken.setRegistry(operatorFilterRegistry.address); + await UnregisteredToken.registerAndSubscribe( + operatorFilterSubscription.address, + true + ); + + expect( + await operatorFilterRegistry.subscriptionOf(UnregisteredToken.address) + ).to.be.equal(operatorFilterSubscription.address); + }); + + it('should be registered through when zero address subscription is passed', async function () { + const {operatorFilterRegistry, UnregisteredToken} = + await setupOperatorFilter(); + + await UnregisteredToken.setRegistry(operatorFilterRegistry.address); + await UnregisteredToken.registerAndSubscribe(zeroAddress, false); + + expect( + await operatorFilterRegistry.isRegistered(UnregisteredToken.address) + ).to.be.equal(true); + }); + + it('should be registered and copy subscription', async function () { + const { + operatorFilterRegistry, + UnregisteredToken, + operatorFilterSubscription, + mockMarketPlace1, + } = await setupOperatorFilter(); + + await UnregisteredToken.setRegistry(operatorFilterRegistry.address); + await UnregisteredToken.registerAndSubscribe( + operatorFilterSubscription.address, + false + ); + + expect( + await operatorFilterRegistry.isRegistered(UnregisteredToken.address) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.subscriptionOf(UnregisteredToken.address) + ).to.be.equal(zeroAddress); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + UnregisteredToken.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + }); + + it('should be subscribed to common subscription', async function () { + const {operatorFilterRegistry, ERC1155, filterOperatorSubscription} = + await setupOperatorFilter(); + expect( + await operatorFilterRegistry.subscriptionOf(ERC1155.address) + ).to.be.equal(filterOperatorSubscription.address); + }); + + it('default subscription should blacklist Mock Market places 1, 2 and not 3, 4', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + DEFAULT_SUBSCRIPTION, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('common subscription should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + filterOperatorSubscription, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('ERC1155 should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + ERC1155, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it("removing market places from common subscription's blacklist should reflect on ERC1155's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + ERC1155, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash, + false + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + }); + + it("adding market places to common subscription's blacklist should reflect on ERC1155's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace3, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + ERC1155, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash, + true + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC1155.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC1155.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + filterOperatorSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + filterOperatorSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + }); + }); + describe('common signer subscription setup', function () { + it('should be registered', async function () { + const {operatorFilterRegistry, ERC721} = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isRegistered(ERC721.address) + ).to.be.equal(true); + }); + + it('should be subscribed to common subscription', async function () { + const {operatorFilterRegistry, ERC721, operatorFilterSubscription} = + await setupOperatorFilter(); + expect( + await operatorFilterRegistry.subscriptionOf(ERC721.address) + ).to.be.equal(operatorFilterSubscription.address); + }); + + it('default subscription should blacklist Mock Market places 1, 2 and not 3, 4', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + DEFAULT_SUBSCRIPTION, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + DEFAULT_SUBSCRIPTION, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + DEFAULT_SUBSCRIPTION, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('common subscription should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + operatorFilterSubscription, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it('ERC721 should blacklist Mock Market places 1, 2 and not 3, 4 like default subscription', async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + ERC721, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace2.address + ) + ).to.be.equal(true); + + const MockERC1155MarketPlace2CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace2.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace2CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace4.address + ) + ).to.be.equal(false); + + const MockERC1155MarketPlace4CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace4.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace4CodeHash + ) + ).to.be.equal(false); + }); + + it("removing market places from common subscription's blacklist should reflect on ERC721's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace1, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + ERC721, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + const MockERC1155MarketPlace1CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace1.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace1.address, + false + ); + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash, + false + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace1.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace1CodeHash + ) + ).to.be.equal(false); + }); + + it("adding market places to common subscription's blacklist should reflect on ERC721's blacklist", async function () { + const { + operatorFilterRegistry, + mockMarketPlace3, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + ERC721, + } = await setupOperatorFilter(); + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + const MockERC1155MarketPlace3CodeHash = + await operatorFilterRegistry.codeHashOf(mockMarketPlace3.address); + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(false); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(false); + + await operatorFilterRegistryAsOwner.updateOperator( + operatorFilterSubscription.address, + mockMarketPlace3.address, + true + ); + + await operatorFilterRegistryAsOwner.updateCodeHash( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash, + true + ); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + ERC721.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + ERC721.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isOperatorFiltered( + operatorFilterSubscription.address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + expect( + await operatorFilterRegistry.isCodeHashFiltered( + operatorFilterSubscription.address, + MockERC1155MarketPlace3CodeHash + ) + ).to.be.equal(true); + }); + }); + describe('transfer and approval ', function () { + it('should be able to approve black listed market places if operator filterer registry is not set on token', async function () { + const { + UnregisteredToken, + users, + operatorFilterSubscription, + mockMarketPlace1, + } = await setupOperatorFilter(); + + await UnregisteredToken.registerAndSubscribe( + operatorFilterSubscription.address, + true + ); + + await users[0].UnregisteredToken.setApprovalForAll( + mockMarketPlace1.address, + true + ); + + expect( + await UnregisteredToken.isApprovedForAll( + users[0].address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + }); + + it('should be able to transfer through black listed market places if operator filterer registry is not set on token', async function () { + const { + UnregisteredToken, + users, + operatorFilterSubscription, + mockMarketPlace1, + } = await setupOperatorFilter(); + + await UnregisteredToken.mintWithoutMinterRole(users[0].address, 1, 1); + + await UnregisteredToken.registerAndSubscribe( + operatorFilterSubscription.address, + true + ); + + await users[0].UnregisteredToken.setApprovalForAll( + mockMarketPlace1.address, + true + ); + + expect( + await UnregisteredToken.isApprovedForAll( + users[0].address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + + await mockMarketPlace1.transferTokenForERC1155( + UnregisteredToken.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect( + await UnregisteredToken.balanceOf(users[1].address, 1) + ).to.be.equal(1); + }); + it('should be able to safe transfer if from is the owner of token', async function () { + const {ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].ERC1155.safeTransferFrom( + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('should be able to safe batch transfer if from is the owner of token', async function () { + const {ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + await ERC1155.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].ERC1155.safeBatchTransferFrom( + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await ERC1155.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + + it('should be able to safe transfer if from is the owner of and to is a blacklisted marketplace', async function () { + const {mockMarketPlace1, ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].ERC1155.safeTransferFrom( + users[0].address, + mockMarketPlace1.address, + 1, + 1, + '0x' + ); + + expect(await ERC1155.balanceOf(mockMarketPlace1.address, 1)).to.be.equal( + 1 + ); + }); + + it('should be able to safe batch transfer if from is the owner of and to is a blacklisted marketplace', async function () { + const {mockMarketPlace1, ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + await ERC1155.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].ERC1155.safeBatchTransferFrom( + users[0].address, + mockMarketPlace1.address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await ERC1155.balanceOf(mockMarketPlace1.address, 1)).to.be.equal( + 1 + ); + expect(await ERC1155.balanceOf(mockMarketPlace1.address, 2)).to.be.equal( + 1 + ); + }); + + it('it should not setApprovalForAll blacklisted market places', async function () { + const {mockMarketPlace1, users} = await setupOperatorFilter(); + await expect( + users[0].ERC1155.setApprovalForAll(mockMarketPlace1.address, true) + ).to.be.reverted; + }); + + it('it should setApprovalForAll non blacklisted market places', async function () { + const {mockMarketPlace3, ERC1155, users} = await setupOperatorFilter(); + await users[0].ERC1155.setApprovalForAll(mockMarketPlace3.address, true); + expect( + await ERC1155.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + }); + + it('it should not be able to setApprovalForAll non blacklisted market places after they are blacklisted ', async function () { + const { + mockMarketPlace3, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + ERC1155, + users, + } = await setupOperatorFilter(); + await users[0].ERC1155.setApprovalForAll(mockMarketPlace3.address, true); + + expect( + await ERC1155.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + users[1].ERC1155.setApprovalForAll(mockMarketPlace3.address, true) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to setApprovalForAll non blacklisted market places after there codeHashes are blacklisted ', async function () { + const { + mockMarketPlace3, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + ERC1155, + users, + } = await setupOperatorFilter(); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace3.address + ); + + await users[0].ERC1155.setApprovalForAll(mockMarketPlace3.address, true); + + expect( + await ERC1155.isApprovedForAll( + users[0].address, + mockMarketPlace3.address + ) + ).to.be.equal(true); + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + users[1].ERC1155.setApprovalForAll(mockMarketPlace3.address, true) + ).to.be.revertedWith; + }); + + it('it should be able to setApprovalForAll blacklisted market places after they are removed from the blacklist ', async function () { + const { + mockMarketPlace1, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + ERC1155, + users, + } = await setupOperatorFilter(); + + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace1.address + ); + + await expect( + users[0].ERC1155.setApprovalForAll(mockMarketPlace1.address, true) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + + await users[0].ERC1155.setApprovalForAll(mockMarketPlace1.address, true); + + expect( + await ERC1155.isApprovedForAll( + users[0].address, + mockMarketPlace1.address + ) + ).to.be.equal(true); + }); + + it('it should not be able to transfer through blacklisted market places', async function () { + const {mockMarketPlace1, ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + await expect( + mockMarketPlace1.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to transfer through market places after they are blacklisted', async function () { + const { + mockMarketPlace3, + ERC1155, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + + await mockMarketPlace3.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + mockMarketPlace3.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to transfer through non blacklisted market places', async function () { + const {mockMarketPlace3, ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to transfer through non blacklisted market places after their codeHash is blacklisted', async function () { + const { + mockMarketPlace3, + ERC1155, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 2); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace3.address + ); + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + mockMarketPlace3.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to transfer through blacklisted market places after they are removed from blacklist', async function () { + const { + mockMarketPlace1, + ERC1155, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace1.address + ); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + await expect( + mockMarketPlace1.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + await mockMarketPlace1.transferTokenForERC1155( + ERC1155.address, + users[0].address, + users[1].address, + 1, + 1, + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + }); + + it('it should not be able to batch transfer through blacklisted market places', async function () { + const {mockMarketPlace1, ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + await ERC1155.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + await expect( + mockMarketPlace1.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should not be able to batch transfer through market places after they are blacklisted', async function () { + const { + mockMarketPlace3, + ERC1155, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 2); + await ERC1155.mintWithoutMinterRole(users[0].address, 2, 2); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + + await mockMarketPlace3.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + + expect(await ERC1155.balanceOf(users[1].address, 2)).to.be.equal(1); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace3.address, + true + ); + + await expect( + mockMarketPlace3.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to batch transfer through non blacklisted market places', async function () { + const {mockMarketPlace3, ERC1155, users} = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + await ERC1155.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await ERC1155.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + + it('it should not be able to batch transfer through non blacklisted market places after their codeHash is blacklisted', async function () { + const { + mockMarketPlace3, + ERC1155, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 2); + await ERC1155.mintWithoutMinterRole(users[0].address, 2, 2); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace3.address, + true + ); + await mockMarketPlace3.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await ERC1155.balanceOf(users[1].address, 2)).to.be.equal(1); + + const mockMarketPlace3CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace3.address + ); + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace3CodeHash, + true + ); + + await expect( + mockMarketPlace3.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + }); + + it('it should be able to batch transfer through blacklisted market places after they are removed from blacklist', async function () { + const { + mockMarketPlace1, + ERC1155, + users, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + } = await setupOperatorFilter(); + const mockMarketPlace1CodeHash = + await operatorFilterRegistryAsSubscription.codeHashOf( + mockMarketPlace1.address + ); + await ERC1155.mintWithoutMinterRole(users[0].address, 1, 1); + await ERC1155.mintWithoutMinterRole(users[0].address, 2, 1); + + await users[0].ERC1155.setApprovalForAllWithoutFilter( + mockMarketPlace1.address, + true + ); + + await expect( + mockMarketPlace1.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ) + ).to.be.revertedWithCustomError; + + await operatorFilterRegistryAsSubscription.updateCodeHash( + filterOperatorSubscription.address, + mockMarketPlace1CodeHash, + false + ); + + await operatorFilterRegistryAsSubscription.updateOperator( + filterOperatorSubscription.address, + mockMarketPlace1.address, + false + ); + await mockMarketPlace1.batchTransferTokenERC1155( + ERC1155.address, + users[0].address, + users[1].address, + [1, 2], + [1, 1], + '0x' + ); + + expect(await ERC1155.balanceOf(users[1].address, 1)).to.be.equal(1); + expect(await ERC1155.balanceOf(users[1].address, 2)).to.be.equal(1); + }); + }); +}); diff --git a/packages/dependency-operator-filter/test/fixtures/testFixture.ts b/packages/dependency-operator-filter/test/fixtures/testFixture.ts new file mode 100644 index 0000000000..eb9e53a5c5 --- /dev/null +++ b/packages/dependency-operator-filter/test/fixtures/testFixture.ts @@ -0,0 +1,156 @@ +import {ethers, upgrades} from 'hardhat'; +const DEFAULT_SUBSCRIPTION = '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'; +import {setupUsers} from '../../util'; + +export async function setupOperatorFilter() { + const [ + deployer, + upgradeAdmin, + filterOperatorSubscription, + user1, + user2, + user3, + user4, + ] = await ethers.getSigners(); + const TrustedForwarderFactory = await ethers.getContractFactory( + 'MockTrustedForwarder' + ); + const TrustedForwarder = await TrustedForwarderFactory.deploy(); + + const MockERC1155MarketPlace1Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace1' + ); + + const mockMarketPlace1 = await MockERC1155MarketPlace1Factory.deploy(); + await mockMarketPlace1.deployed(); + + const MockERC1155MarketPlace2Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace2' + ); + + const mockMarketPlace2 = await MockERC1155MarketPlace2Factory.deploy(); + await mockMarketPlace2.deployed(); + + const MockERC1155MarketPlace3Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace3' + ); + + const mockMarketPlace3 = await MockERC1155MarketPlace3Factory.deploy(); + await mockMarketPlace3.deployed(); + + const MockERC1155MarketPlace4Factory = await ethers.getContractFactory( + 'MockERC1155MarketPlace4' + ); + + const mockMarketPlace4 = await MockERC1155MarketPlace4Factory.deploy(); + await mockMarketPlace4.deployed(); + const MockOperatorFilterRegistryFactory = await ethers.getContractFactory( + 'MockOperatorFilterRegistry' + ); + + const operatorFilterRegistry = await MockOperatorFilterRegistryFactory.deploy( + DEFAULT_SUBSCRIPTION, + [mockMarketPlace1.address, mockMarketPlace2.address] + ); + + await operatorFilterRegistry.deployed(); + const operatorFilterRegistryAsSubscription = operatorFilterRegistry.connect( + filterOperatorSubscription + ); + const tnx = await operatorFilterRegistryAsSubscription.registerAndCopyEntries( + filterOperatorSubscription.address, + DEFAULT_SUBSCRIPTION + ); + + await tnx.wait(); + const ERC1155Factory = await ethers.getContractFactory('TestERC1155'); + const ERC1155 = await upgrades.deployProxy( + ERC1155Factory, + ['testERC1155', TrustedForwarder.address], + { + initializer: 'initialize', + } + ); + + let MockOperatorFilterSubscriptionFactory = await ethers.getContractFactory( + 'MockOperatorFilterSubscription' + ); + + MockOperatorFilterSubscriptionFactory = + await MockOperatorFilterSubscriptionFactory.connect(deployer); + + const operatorFilterSubscription = + await MockOperatorFilterSubscriptionFactory.deploy( + deployer.address, + operatorFilterRegistry.address + ); + + const operatorFilterRegistryAsOwner = await operatorFilterRegistry.connect( + deployer + ); + + const ERC721Factory = await ethers.getContractFactory('TestERC721'); + const ERC721 = await upgrades.deployProxy( + ERC721Factory, + ['test', 'testERC721', TrustedForwarder.address], + { + initializer: 'initialize', + } + ); + await ERC721.deployed(); + const tnx2 = await ERC1155.setRegistryAndSubscribe( + operatorFilterRegistry.address, + filterOperatorSubscription.address + ); + await tnx2.wait(); + + const tnx3 = await ERC721.setRegistryAndSubscribe( + operatorFilterRegistry.address, + operatorFilterSubscription.address + ); + await tnx3.wait(); + + const UnregisteredTokenFactory = await ethers.getContractFactory( + 'UnregisteredToken' + ); + const UnregisteredToken = await upgrades.deployProxy( + UnregisteredTokenFactory, + [ + 'UnregisteredToken', + operatorFilterSubscription.address, + true, + TrustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + + const users = await setupUsers( + [user1.address, user2.address, user3.address, user4.address], + { + ERC1155, + ERC721, + UnregisteredToken, + } + ); + + return { + mockMarketPlace1, + mockMarketPlace2, + mockMarketPlace3, + mockMarketPlace4, + operatorFilterRegistry, + operatorFilterRegistryAsSubscription, + filterOperatorSubscription, + users, + deployer, + upgradeAdmin, + ERC1155, + DEFAULT_SUBSCRIPTION, + operatorFilterRegistryAsOwner, + operatorFilterSubscription, + ERC721, + UnregisteredToken, + }; +} diff --git a/packages/dependency-operator-filter/tsconfig.json b/packages/dependency-operator-filter/tsconfig.json new file mode 100644 index 0000000000..790a8309cf --- /dev/null +++ b/packages/dependency-operator-filter/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + }, + "include": [ + "hardhat.config.ts", + "./typechain-types", + "./test" + ] +} diff --git a/packages/dependency-operator-filter/util.ts b/packages/dependency-operator-filter/util.ts new file mode 100644 index 0000000000..4ad6401463 --- /dev/null +++ b/packages/dependency-operator-filter/util.ts @@ -0,0 +1,231 @@ +/* eslint-disable mocha/no-exports */ +import {BigNumber} from '@ethersproject/bignumber'; +import { + Contract, + ContractReceipt, + ContractTransaction, + Event, + utils, +} from 'ethers'; +import {Receipt} from 'hardhat-deploy/types'; +import {Result} from 'ethers/lib/utils'; +import {deployments, ethers, network} from 'hardhat'; +import {FixtureFunc} from 'hardhat-deploy/dist/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +export async function sequentially( + arr: Array, + callbackfn: (value: S, index: number, array: S[]) => Promise +): Promise { + const ret = []; + for (let i = 0; i < arr.length; i++) { + ret.push(await callbackfn(arr[i], i, arr)); + } + return ret; +} + +export async function mine(): Promise { + await ethers.provider.send('evm_mine', []); +} + +export async function increaseTime( + numSec: number, + callMine = true +): Promise { + // must do something (mine, send a tx) to move the time + await ethers.provider.send('evm_increaseTime', [numSec]); + if (callMine) await mine(); +} + +export async function getTime(): Promise { + const latestBlock = await ethers.provider.getBlock('latest'); + return latestBlock.timestamp; +} + +export async function setNextBlockTime( + time: number, + callMine = false +): Promise { + // must do something (mine, send a tx) to move the time + await ethers.provider.send('evm_setNextBlockTimestamp', [time]); + if (callMine) await mine(); +} + +type Test = { + title: string; + subTests?: Test[]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + test: any; +}; + +export function recurseTests(test: Test): void { + /* eslint-disable mocha/no-setup-in-describe */ + if (test.subTests) { + describe(test.title, function () { + if (test.subTests) { + for (const subTest of test.subTests) { + recurseTests(subTest); + } + } + }); + } else { + it(test.title, test.test); + } + /* eslint-enable mocha/no-setup-in-describe */ +} + +export function toWei(number: string | number | BigNumber): BigNumber { + return BigNumber.from(number).mul('1000000000000000000'); +} + +export function cubeRoot6(bigNum: BigNumber): BigNumber { + const DECIMALS_18 = BigNumber.from(1).mul('1000000000000000000'); + const a = bigNum.mul(DECIMALS_18); + const base = BigNumber.from(2); + const root = BigNumber.from(3); + let tmp = a.add(base).div(root); + let c = a; + while (tmp.lt(c)) { + c = tmp; + const tmpSquare = tmp.mul(tmp); + const numerator = a.div(tmpSquare).add(tmp.mul(base)); + tmp = numerator.div(root); + } + return c; +} + +export async function findEvents( + contract: Contract, + event: string, + blockHash: string +): Promise { + const filter = contract.filters[event](); + return await contract.queryFilter(filter, blockHash); +} + +export type EventWithArgs = Event & {args: Result}; + +export async function expectReceiptEventWithArgs( + receipt: ContractReceipt, + name: string +): Promise { + if (!receipt.events) { + throw new Error('no events'); + } + for (const event of receipt.events) { + if (event.event === name) { + if (!event.args) { + throw new Error('event has no args'); + } + return event as EventWithArgs; + } + } + throw new Error('no matching events'); +} + +export async function expectEventWithArgs( + contract: Contract, + receipt: ContractReceipt, + event: string +): Promise { + const events = await findEvents(contract, event, receipt.blockHash); + if (events.length == 0) { + throw new Error('no events'); + } + if (!events[0].args) { + throw new Error('event has no args'); + } + return events[0] as EventWithArgs; +} + +export async function expectEventWithArgsFromReceipt( + contract: Contract, + receipt: Receipt, + event: string +): Promise { + const events = await findEvents(contract, event, receipt.blockHash); + if (events.length == 0) { + throw new Error('no events'); + } + if (!events[0].args) { + throw new Error('event has no args'); + } + return events[0] as EventWithArgs; +} + +export function waitFor( + p: Promise +): Promise { + return p.then((tx) => tx.wait()); +} + +type Contracts = Record; + +export async function setupUsers( + addresses: string[], + contracts: T +): Promise<({address: string} & T)[]> { + const users: ({address: string} & T)[] = []; + for (const address of addresses) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const user: any = {address}; + for (const key of Object.keys(contracts)) { + user[key] = contracts[key].connect(await ethers.getSigner(address)); + } + users.push(user); + } + return users; +} + +export async function setupUser( + address: string, + contracts: T +): Promise<{address: string} & T> { + const users = await setupUsers([address], contracts); + return users[0]; +} + +export function getNftIndex(id: BigNumber): number { + // js bitwise & operands are converted to 32-bit integers + const idAsHexString = utils.hexValue(id); + const slicedId = Number('0x' + idAsHexString.slice(48, 56)); + const SLICED_NFT_INDEX_MASK = Number('0x7F800000'); + return (slicedId & SLICED_NFT_INDEX_MASK) >>> 23; +} + +export function getAssetChainIndex(id: BigNumber): number { + // js bitwise & operands are converted to 32-bit integers + const idAsHexString = utils.hexValue(id); + const slicedId = Number('0x' + idAsHexString.slice(42, 50)); + const SLICED_CHAIN_INDEX_MASK = Number('0x7F800000'); + return (slicedId & SLICED_CHAIN_INDEX_MASK) >>> 23; +} + +export async function evmRevertToInitialState(): Promise { + console.log('Revert to initial snapshot, calling reset'); + // This revert the evm state. + await network.provider.request({ + method: 'hardhat_reset', + params: [network.config], + }); +} + +export function withSnapshot( + tags: string | string[] = [], + func: FixtureFunc = async () => { + return {}; + } +): (options?: O) => Promise { + return deployments.createFixture( + async (env: HardhatRuntimeEnvironment, options?: O) => { + // TODO: This has problems with solidity-coverage, when the fix that we can use it + // TODO: We need a way to revert to initial state!!! + // await evmRevertToInitialState(); + await deployments.fixture(tags, { + fallbackToGlobal: false, + keepExistingDeployments: false, + }); + return func(env, options); + } + ); +} diff --git a/packages/dependency-royalty-management/.eslintignore b/packages/dependency-royalty-management/.eslintignore new file mode 100644 index 0000000000..a77e23ebbf --- /dev/null +++ b/packages/dependency-royalty-management/.eslintignore @@ -0,0 +1,16 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts + +# generated docs +generated-markups + +# editors +.idea diff --git a/packages/dependency-royalty-management/.eslintrc.js b/packages/dependency-royalty-management/.eslintrc.js new file mode 100644 index 0000000000..e734de4058 --- /dev/null +++ b/packages/dependency-royalty-management/.eslintrc.js @@ -0,0 +1,41 @@ +const path = require('path'); +const tsconfigPath = path.join(__dirname, 'tsconfig.json'); +module.exports = { + root: true, + extends: [ + 'eslint:recommended', + 'plugin:mocha/recommended', + 'plugin:prettier/recommended', + ], + parserOptions: { + ecmaVersion: 2020, + }, + plugins: ['mocha'], + env: { + commonjs: true, + node: true, + mocha: true, + }, + overrides: [ + { + files: ['*.ts'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: [tsconfigPath], + ecmaVersion: 2020, + sourceType: 'module', + }, + plugins: ['mocha', '@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:mocha/recommended', + 'plugin:prettier/recommended', + ], + rules: { + '@typescript-eslint/no-misused-promises': 'error', + '@typescript-eslint/no-floating-promises': 'error', + }, + }, + ], +}; diff --git a/packages/dependency-royalty-management/.gitignore b/packages/dependency-royalty-management/.gitignore new file mode 100644 index 0000000000..04e3058747 --- /dev/null +++ b/packages/dependency-royalty-management/.gitignore @@ -0,0 +1,15 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts +./artifacts +./cache +./typechain + +deployments \ No newline at end of file diff --git a/packages/dependency-royalty-management/.prettierignore b/packages/dependency-royalty-management/.prettierignore new file mode 100644 index 0000000000..a77e23ebbf --- /dev/null +++ b/packages/dependency-royalty-management/.prettierignore @@ -0,0 +1,16 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts + +# generated docs +generated-markups + +# editors +.idea diff --git a/packages/dependency-royalty-management/.prettierrc.js b/packages/dependency-royalty-management/.prettierrc.js new file mode 100644 index 0000000000..60dbb58db3 --- /dev/null +++ b/packages/dependency-royalty-management/.prettierrc.js @@ -0,0 +1,15 @@ +module.exports = { + singleQuote: true, + bracketSpacing: false, + plugins: ['prettier-plugin-solidity'], + overrides: [ + { + files: '*.sol', + options: { + printWidth: 120, + tabWidth: 4, + singleQuote: false, + }, + }, + ], +}; diff --git a/packages/dependency-royalty-management/.solcover.js b/packages/dependency-royalty-management/.solcover.js new file mode 100644 index 0000000000..f6c4e5445d --- /dev/null +++ b/packages/dependency-royalty-management/.solcover.js @@ -0,0 +1,7 @@ +module.exports = { + mocha: { + grep: '@skip-on-coverage', // Find everything with this tag + invert: true, // Run the grep's inverse set. + }, + skipFiles: ['/mock'], +}; diff --git a/packages/dependency-royalty-management/.solhint.json b/packages/dependency-royalty-management/.solhint.json new file mode 100644 index 0000000000..d722fc1342 --- /dev/null +++ b/packages/dependency-royalty-management/.solhint.json @@ -0,0 +1,15 @@ +{ + "extends": "solhint:recommended", + "plugins": ["prettier"], + "rules": { + "prettier/prettier": [ + "error", + { + "endOfLine": "auto" + } + ], + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["error", {"ignoreConstructors": true}], + "reason-string": ["warn", {"maxLength": 64}] + } +} diff --git a/packages/dependency-royalty-management/.solhintignore b/packages/dependency-royalty-management/.solhintignore new file mode 100644 index 0000000000..d28fc94993 --- /dev/null +++ b/packages/dependency-royalty-management/.solhintignore @@ -0,0 +1 @@ +contracts/mock diff --git a/packages/dependency-royalty-management/README.md b/packages/dependency-royalty-management/README.md new file mode 100644 index 0000000000..4ea6780885 --- /dev/null +++ b/packages/dependency-royalty-management/README.md @@ -0,0 +1,67 @@ +# + +The Sandbox's royalty dependency package, for use by The Sandbox's token contracts. +This is a dependency package, and the smart contracts inside use floating pragma. + +## Running the project locally + +Install dependencies with `yarn` + +Testing: Use `yarn test` inside `packages/` to run tests locally inside this package + +For testing from root (with workspace feature) use: `yarn workspace @sandbox-smart-contracts/ test` + +Coverage: Run `yarn coverage` + +Formatting: Run `yarn prettier` to check and `yarn prettier:fix` to fix formatting errors + +Linting: Run `yarn lint` to check and `yarn lint:fix` to fix static analysis errors + +## Package structure and minimum standards + +#### A NOTE ON DEPENDENCIES + +1. Add whatever dependencies you like inside your package; this template is for hardhat usage. OpenZeppelin contracts + are highly recommended and should be installed as a dev dependency +2. For most Pull Requests there should be minimum changes to `yarn.lock` at root level +3. Changes to root-level dependencies are permissible, however they should not be downgraded +4. Take care to run `yarn` before pushing your changes +5. You shouldn't need to install dotenv since you won't be deploying inside this package (see below) + +#### UNIT TESTING + +1. Unit tests are to be added in `packages//test` +2. Coverage must meet minimum requirements for CI to pass +3. `getSigners` return an array of addresses, the first one is the default `deployer` for contracts, under no + circumstances should tests be written as `deployer` +4. It's permissible to create mock contracts at `packages//contracts/mock` e.g. for third-party contracts +5. Tests must not rely on any deploy scripts from the `deploy` package; your contracts must be deployed inside the test + fixture. See `test/fixtures.ts` + +# Deployment + +Each package must unit-test the contracts by running everything inside the `hardhat node`. Deployment to "real" +networks, configuration of our environment and integration tests must be done inside the `deploy` package. + +The `deploy` package only imports `.sol` files. The idea is to recompile everything inside it and manage the entire +deploy strategy from one place. + +1. Your deploy scripts should not be included inside `packages/`: deploy scripts live inside `packages/deploy/` +2. The `deploy` package doesn't use the hardhat config file from the specific package. Instead, it + uses `packages/deploy/hardhat.config.ts` +3. You will need to review `packages/deploy/hardhat.config.ts` and update it as needed for any new namedAccounts you + added to your package +4. When it comes to deploy time, it is preferred to include deploy scripts and end-to-end tests as a separate PR +5. The named accounts inside the `deploy` package must use the "real-life" values +6. Refer to the readme at `packages/deploy` to learn more about importing your package + +#### INTEGRATION TESTING + +1. End-to-end tests live at `packages/deploy/` +2. You must add end-to-end tests ahead of deploying your package. Importantly, these tests should verify deployment and + initialization configuration + +# A NOTE ON MAKING PULL REQUESTS + +1. Follow the PR template checklist +2. Your PR will not be approved if the above criteria are not met diff --git a/packages/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol b/packages/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol new file mode 100644 index 0000000000..50078e5be9 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; +import {IMultiRoyaltyDistributor, IMultiRoyaltyRecipients} from "./interfaces/IMultiRoyaltyDistributor.sol"; +import { + IRoyaltySplitter, + IERC165 +} from "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol"; +import {IEIP2981} from "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol"; +import {IRoyaltyManager, Recipient} from "./interfaces/IRoyaltyManager.sol"; + +/// @title MultiRoyaltyDistributor +/// @author The Sandbox +/// @dev The MultiRoyaltyDistributor contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters. +/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to split its royalty between the creator and Sandbox and use it for every token minted by that creator. +abstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable { + uint16 internal constant TOTAL_BASIS_POINTS = 10000; + address private royaltyManager; + + mapping(uint256 => address payable) private _tokenRoyaltiesSplitter; + uint256[] private _tokensWithRoyalties; + + // solhint-disable-next-line func-name-mixedcase + function __MultiRoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing { + _setRoyaltyManager(_royaltyManager); + __ERC165_init_unchained(); + } + + /// @notice Query if a contract implements interface `id`. + /// @param interfaceId the interface identifier, as specified in ERC-165. + /// @return isSupported `true` if the contract implements `id`. + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC165Upgradeable, IERC165) + returns (bool isSupported) + { + return + interfaceId == type(IEIP2981).interfaceId || + interfaceId == type(IMultiRoyaltyDistributor).interfaceId || + interfaceId == type(IMultiRoyaltyRecipients).interfaceId || + super.supportsInterface(interfaceId); + } + + /// @notice sets token royalty + /// @dev deploys a splitter if a creator doesn't have one + /// @param tokenId id of token + /// @param recipient royalty recipient + /// @param creator of the token + function _setTokenRoyalties( + uint256 tokenId, + address payable recipient, + address creator + ) internal { + address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient); + + if (_tokenRoyaltiesSplitter[tokenId] != address(0)) { + if (_tokenRoyaltiesSplitter[tokenId] != creatorSplitterAddress) { + _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress); + } + } else { + _tokensWithRoyalties.push(tokenId); + _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress); + } + } + + /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount + /// @param tokenId of the token for which the royalty is needed to be distributed + /// @param value the amount on which the royalty is calculated + /// @return receiver address the royalty receiver + /// @return royaltyAmount value the EIP2981 royalty + function royaltyInfo(uint256 tokenId, uint256 value) + public + view + override + returns (address receiver, uint256 royaltyAmount) + { + (address payable _defaultRoyaltyReceiver, uint16 _defaultRoyaltyBPS) = + IRoyaltyManager(royaltyManager).getRoyaltyInfo(); + if (_tokenRoyaltiesSplitter[tokenId] != address(0)) { + return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS); + } + if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) { + return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS); + } + return (address(0), 0); + } + + /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver. + /// @return splits the royalty receiver's array + function getAllSplits() external view override returns (address payable[] memory splits) { + uint256 startingIndex; + uint256 endingIndex = _tokensWithRoyalties.length; + (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo(); + if (_defaultRoyaltyReceiver != address(0)) { + splits = new address payable[](1 + _tokensWithRoyalties.length); + splits[0] = _defaultRoyaltyReceiver; + startingIndex = 1; + ++endingIndex; + } else { + // unreachable in practice + splits = new address payable[](_tokensWithRoyalties.length); + } + for (uint256 i = startingIndex; i < endingIndex; ++i) { + splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]]; + } + } + + /// @notice returns the royalty recipients for each tokenId. + /// @dev returns the default address for tokens with no recipients. + /// @param tokenId is the token id for which the recipient should be returned. + /// @return recipients array of royalty recipients for the token + function getRecipients(uint256 tokenId) public view returns (Recipient[] memory recipients) { + address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId]; + (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo(); + if (splitterAddress != address(0)) { + return IRoyaltySplitter(splitterAddress).getRecipients(); + } + recipients = new Recipient[](1); + recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS}); + return recipients; + } + + /// @notice internal function to set the token royalty splitter + /// @param tokenId id of token + /// @param splitterAddress address of the splitter contract + function _setTokenRoyaltiesSplitter(uint256 tokenId, address payable splitterAddress) internal { + _tokenRoyaltiesSplitter[tokenId] = splitterAddress; + emit TokenRoyaltySplitterSet(tokenId, splitterAddress); + } + + /// @notice returns the address of token royalty splitter. + /// @param tokenId is the token id for which royalty splitter should be returned. + /// @return splitterAddress address of royalty splitter for the token + function getTokenRoyaltiesSplitter(uint256 tokenId) external view returns (address payable splitterAddress) { + return _tokenRoyaltiesSplitter[tokenId]; + } + + /// @notice returns the address of royalty manager. + /// @return managerAddress address of royalty manager. + function getRoyaltyManager() external view returns (address managerAddress) { + return royaltyManager; + } + + /// @notice set royalty manager address + /// @param _royaltyManager address of royalty manager to set + function _setRoyaltyManager(address _royaltyManager) internal { + royaltyManager = _royaltyManager; + emit RoyaltyManagerSet(_royaltyManager); + } + + uint256[47] private __gap; +} diff --git a/packages/dependency-royalty-management/contracts/RoyaltyDistributor.sol b/packages/dependency-royalty-management/contracts/RoyaltyDistributor.sol new file mode 100644 index 0000000000..0fa83a271e --- /dev/null +++ b/packages/dependency-royalty-management/contracts/RoyaltyDistributor.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC2981Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol"; +import {IRoyaltyManager} from "./interfaces/IRoyaltyManager.sol"; +import { + ERC165Upgradeable, + IERC165Upgradeable +} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; + +/// @title RoyaltyDistributor +/// @author The Sandbox +/// @notice Contract for distributing royalties based on the ERC2981 standard. +abstract contract RoyaltyDistributor is IERC2981Upgradeable, ERC165Upgradeable { + event RoyaltyManagerSet(address indexed _royaltyManager); + uint16 internal constant TOTAL_BASIS_POINTS = 10000; + IRoyaltyManager private royaltyManager; + + // solhint-disable-next-line func-name-mixedcase + function __RoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing { + _setRoyaltyManager(_royaltyManager); + __ERC165_init_unchained(); + } + + /// @notice Returns how much royalty is owed and to whom based on ERC2981 + /// @dev tokenId is one of the EIP2981 args for this function can't be removed + /// @param _salePrice the price of token on which the royalty is calculated + /// @return receiver the receiver of royalty + /// @return royaltyAmount the amount of royalty + function royaltyInfo( + uint256, /*_tokenId */ + uint256 _salePrice + ) external view returns (address receiver, uint256 royaltyAmount) { + uint16 royaltyBps; + (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo(); + royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS; + return (receiver, royaltyAmount); + } + + /// @notice Query if a contract implements interface `id`. + /// @param interfaceId the interface identifier, as specified in ERC-165. + /// @return isSupported `true` if the contract implements `id`. + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC165Upgradeable, IERC165Upgradeable) + returns (bool isSupported) + { + return (interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId)); + } + + /// @notice returns the royalty manager + /// @return royaltyManagerAddress address of royalty manager contract. + function getRoyaltyManager() external view returns (IRoyaltyManager royaltyManagerAddress) { + return royaltyManager; + } + + /// @notice set royalty manager + /// @param _royaltyManager address of royalty manager to set + function _setRoyaltyManager(address _royaltyManager) internal { + royaltyManager = IRoyaltyManager(_royaltyManager); + emit RoyaltyManagerSet(_royaltyManager); + } + + uint256[49] private __gap; +} diff --git a/packages/dependency-royalty-management/contracts/RoyaltyManager.sol b/packages/dependency-royalty-management/contracts/RoyaltyManager.sol new file mode 100644 index 0000000000..0bc532654f --- /dev/null +++ b/packages/dependency-royalty-management/contracts/RoyaltyManager.sol @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.0; + +import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; +import {IRoyaltyManager} from "./interfaces/IRoyaltyManager.sol"; +import {Recipient} from "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol"; +import {RoyaltySplitter} from "./RoyaltySplitter.sol"; +import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; + +/// @title RoyaltyManager +/// @author The Sandbox +/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info +/// for contracts that don't use the RoyaltySplitter. +contract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager { + bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256("CONTRACT_ROYALTY_SETTER_ROLE"); + bytes32 public constant SPLITTER_DEPLOYER_ROLE = keccak256("SPLITTER_DEPLOYER_ROLE"); + + uint16 internal constant TOTAL_BASIS_POINTS = 10000; + uint16 public commonSplit; + address payable public commonRecipient; + mapping(address => uint16) public contractRoyalty; + mapping(address => address payable) public creatorRoyaltiesSplitter; + address internal _royaltySplitterCloneable; + address internal _trustedForwarder; + + /// @dev this protects the implementation contract from behing initialized. + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice initialization function for the deployment of contract + /// @dev called during the deployment via the proxy. + /// @param _commonRecipient the != address(0)common recipient for all the splitters + /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit + /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution + /// @param managerAdmin address of RoyaltyManager contract. + /// @param contractRoyaltySetter the address of royalty setter of contract. + /// @param trustedForwarder the trustedForwarder address for royalty splitters to use. + function initialize( + address payable _commonRecipient, + uint16 _commonSplit, + address royaltySplitterCloneable, + address managerAdmin, + address contractRoyaltySetter, + address trustedForwarder + ) external initializer { + _setRecipient(_commonRecipient); + _setSplit(_commonSplit); + _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin); + _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter); + _royaltySplitterCloneable = royaltySplitterCloneable; + _setTrustedForwarder(trustedForwarder); + } + + /// @notice sets royalty recipient wallet + /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract. + /// @param recipient new recipient wallet. + function setRoyaltyRecipient(address payable recipient) external { + address payable _creatorSplitterAddress = creatorRoyaltiesSplitter[msg.sender]; + require(_creatorSplitterAddress != address(0), "Manager: No splitter deployed for the creator"); + address _recipient = RoyaltySplitter(_creatorSplitterAddress).recipient(); + require(_recipient != recipient, "Manager: Recipient already set"); + Recipient[] memory newRecipient = new Recipient[](1); + newRecipient[0] = Recipient({recipient: recipient, bps: 0}); + RoyaltySplitter(_creatorSplitterAddress).setRecipients(newRecipient); + } + + /// @notice sets the common recipient + /// @dev can only be called by the admin + /// @param _commonRecipient is the common recipient for all the splitters + function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) { + _setRecipient(_commonRecipient); + } + + /// @notice sets the trustedForwarder address to be used by the splitters + /// @dev can only be called by the admin + /// new splitters will read this value + /// @param _newForwarder is the new trusted forwarder address + function setTrustedForwarder(address _newForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) { + _setTrustedForwarder(_newForwarder); + } + + /// @notice sets the common split + /// @dev can only be called by the admin. + /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit + function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) { + _setSplit(_commonSplit); + } + + /// @notice get the current trustedForwarder address + /// @return trustedForwarder address of current TrustedForwarder + function getTrustedForwarder() external view returns (address trustedForwarder) { + return _trustedForwarder; + } + + function _setRecipient(address payable _commonRecipient) internal { + require(_commonRecipient != address(0), "Manager: Can't set common recipient to zero address"); + commonRecipient = _commonRecipient; + emit RecipientSet(_commonRecipient); + } + + function _setSplit(uint16 _commonSplit) internal { + require(_commonSplit < TOTAL_BASIS_POINTS, "Manager: Can't set split greater than the total basis point"); + commonSplit = _commonSplit; + emit SplitSet(_commonSplit); + } + + /// @notice sets trusted forwarder address + /// @param _newForwarder new trusted forwarder address to set + function _setTrustedForwarder(address _newForwarder) internal { + address oldTrustedForwarder = _trustedForwarder; + _trustedForwarder = _newForwarder; + emit TrustedForwarderSet(oldTrustedForwarder, _newForwarder); + } + + /// @notice called to set the EIP 2981 royalty split + /// @dev can only be called by contract royalty setter. + /// @param contractAddress address of contract for which royalty is set + /// @param _royaltyBps the royalty split for the EIP 2981 + function setContractRoyalty(address contractAddress, uint16 _royaltyBps) + external + onlyRole(CONTRACT_ROYALTY_SETTER_ROLE) + { + require(_royaltyBps < TOTAL_BASIS_POINTS, "Manager: Royalty can't be greater than Total base points"); + contractRoyalty[contractAddress] = _royaltyBps; + emit RoyaltySet(_royaltyBps, contractAddress); + } + + /// @notice to be called by the splitters to get the common recipient and split + /// @return recipient which has the common recipient and split + function getCommonRecipient() external view override returns (Recipient memory recipient) { + return Recipient({recipient: commonRecipient, bps: commonSplit}); + } + + /// @notice deploys splitter for creator + /// @dev should only called once per creator + /// @param creator the address of the creator + /// @param recipient the wallet of the recipient where they would receive their royalty + /// @return creatorSplitterAddress splitter's address deployed for a creator + function deploySplitter(address creator, address payable recipient) + external + onlyRole(SPLITTER_DEPLOYER_ROLE) + returns (address payable creatorSplitterAddress) + { + creatorSplitterAddress = creatorRoyaltiesSplitter[creator]; + if (creatorSplitterAddress == address(0)) { + creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable)); + RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this)); + creatorRoyaltiesSplitter[creator] = creatorSplitterAddress; + emit SplitterDeployed(creator, recipient, creatorSplitterAddress); + } + return creatorSplitterAddress; + } + + /// @notice returns the address of splitter of a creator. + /// @param creator the address of the creator + /// @return creatorSplitterAddress splitter's address deployed for a creator + function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress) { + return creatorRoyaltiesSplitter[creator]; + } + + /// @notice returns the amount of basis points allocated to the creator + /// @return creatorSplit which is 10000 - commonSplit + function getCreatorSplit() external view returns (uint16 creatorSplit) { + return TOTAL_BASIS_POINTS - commonSplit; + } + + /// @notice returns the commonRecipient and EIP2981 royalty bps + /// @return recipient address of common royalty recipient + /// @return royaltySplit contract EIP2981 royalty bps + function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit) { + return (commonRecipient, contractRoyalty[msg.sender]); + } + + /// @notice returns the EIP2981 royalty bps + /// @param _contractAddress the address of the contract for which the royalty is required + /// @return royaltyBps royalty bps of the contract + function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) { + return contractRoyalty[_contractAddress]; + } + + uint256[44] private __gap; +} diff --git a/packages/dependency-royalty-management/contracts/RoyaltySplitter.sol b/packages/dependency-royalty-management/contracts/RoyaltySplitter.sol new file mode 100644 index 0000000000..ff9a0e2204 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/RoyaltySplitter.sol @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.0; + +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import { + OwnableUpgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {AddressUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; +import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; +import {SafeMath} from "@openzeppelin/contracts/utils/math/SafeMath.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {BytesLibrary} from "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol"; +import { + IRoyaltySplitter, + IERC165, + Recipient +} from "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol"; +import {ERC2771HandlerAbstract} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol"; +import {IRoyaltyManager} from "./interfaces/IRoyaltyManager.sol"; +import {IERC20Approve} from "./interfaces/IERC20Approve.sol"; + +/// @title RoyaltySplitter +/// @author The Sandbox +/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share. +contract RoyaltySplitter is + Initializable, + OwnableUpgradeable, + IRoyaltySplitter, + ERC165Upgradeable, + ERC2771HandlerAbstract +{ + using BytesLibrary for bytes; + using AddressUpgradeable for address payable; + using AddressUpgradeable for address; + using SafeMath for uint256; + using SafeERC20 for IERC20; + + uint256 internal constant TOTAL_BASIS_POINTS = 10000; + + address payable public recipient; + IRoyaltyManager public royaltyManager; + + event ETHTransferred(address indexed account, uint256 amount); + event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount); + event RecipientSet(address indexed recipientAddress); + + /// @dev this protects the implementation contract from behing initialized. + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + /// @notice Query if a contract implements interface `id`. + /// @param interfaceId the interface identifier, as specified in ERC-165. + /// @return isSupported `true` if the contract implements `id`. + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(IERC165, ERC165Upgradeable) + returns (bool isSupported) + { + return (interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId)); + } + + /// @notice initialize the contract + /// @dev can only be run once. + /// @param recipientAddress the wallet of the creator when the contract is deployed + /// @param _royaltyManager the address of the royalty manager contract + function initialize(address payable recipientAddress, address _royaltyManager) external initializer { + royaltyManager = IRoyaltyManager(_royaltyManager); // set manager before Ownable_init for _isTrustedForwarder + _setRecipient(recipientAddress); + __Ownable_init(); + __ERC165_init(); + } + + /// @notice sets recipient for the splitter + /// @dev only the owner can call this. + /// @param recipients the array of recipients which should only have one recipient. + function setRecipients(Recipient[] calldata recipients) external override onlyOwner { + require(recipients.length == 1, "Invalid recipents length"); + _setRecipient(recipients[0].recipient); + } + + function _setRecipient(address payable recipientAddress) private { + recipient = recipientAddress; + emit RecipientSet(recipientAddress); + } + + /// @notice to get recipients of royalty through this splitter and their splits of royalty. + /// @return recipients array of royalty recipients through the splitter and their splits of royalty. + function getRecipients() external view override returns (Recipient[] memory recipients) { + Recipient memory commonRecipient = royaltyManager.getCommonRecipient(); + uint16 creatorSplit = royaltyManager.getCreatorSplit(); + recipients = new Recipient[](2); + recipients[0].recipient = recipient; + recipients[0].bps = creatorSplit; + recipients[1] = commonRecipient; + return recipients; + } + + /// @notice Splits and forwards ETH to the royalty receivers + /// @dev splits ETH every time it is sent to this contract as royalty. + receive() external payable { + _splitETH(msg.value); + } + + /// @notice Splits and forwards ETH to the royalty receivers + /// @dev normally ETH should be split automatically by receive function. + function splitETH() external payable { + _splitETH(address(this).balance); + } + + function _splitETH(uint256 value) internal { + if (value > 0) { + Recipient memory commonRecipient = royaltyManager.getCommonRecipient(); + uint16 creatorSplit = royaltyManager.getCreatorSplit(); + Recipient[] memory _recipients = new Recipient[](2); + _recipients[0].recipient = recipient; + _recipients[0].bps = creatorSplit; + _recipients[1] = commonRecipient; + uint256 totalSent; + uint256 amountToSend; + unchecked { + for (uint256 i = _recipients.length - 1; i > 0; i--) { + Recipient memory _recipient = _recipients[i]; + amountToSend = (value * _recipient.bps) / TOTAL_BASIS_POINTS; + totalSent += amountToSend; + _recipient.recipient.sendValue(amountToSend); + emit ETHTransferred(_recipient.recipient, amountToSend); + } + // Favor the 1st recipient if there are any rounding issues + amountToSend = value - totalSent; + } + _recipients[0].recipient.sendValue(amountToSend); + emit ETHTransferred(_recipients[0].recipient, amountToSend); + } + } + + /// @notice split ERC20 Tokens owned by this contract. + /// @dev can only be called by one of the recipients + /// @param erc20Contract the address of the tokens to be split. + function splitERC20Tokens(IERC20 erc20Contract) external { + require(_splitERC20Tokens(erc20Contract), "Split: ERC20 split failed"); + } + + function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool success) { + try erc20Contract.balanceOf(address(this)) returns (uint256 balance) { + if (balance == 0) { + return false; + } + Recipient memory commonRecipient = royaltyManager.getCommonRecipient(); + uint16 creatorSplit = royaltyManager.getCreatorSplit(); + require( + commonRecipient.recipient == _msgSender() || recipient == _msgSender(), + "Split: Can only be called by one of the recipients" + ); + Recipient[] memory _recipients = new Recipient[](2); + _recipients[0].recipient = recipient; + _recipients[0].bps = creatorSplit; + _recipients[1] = commonRecipient; + uint256 amountToSend; + uint256 totalSent; + unchecked { + for (uint256 i = _recipients.length - 1; i > 0; i--) { + Recipient memory _recipient = _recipients[i]; + (success, amountToSend) = balance.tryMul(_recipient.bps); + require(success, "RoyaltySplitter: Multiplication Overflow"); + + amountToSend /= TOTAL_BASIS_POINTS; + totalSent += amountToSend; + + erc20Contract.safeTransfer(_recipient.recipient, amountToSend); + emit ERC20Transferred(address(erc20Contract), _recipient.recipient, amountToSend); + } + // Favor the 1st recipient if there are any rounding issues + amountToSend = balance - totalSent; + } + erc20Contract.safeTransfer(_recipients[0].recipient, amountToSend); + emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend); + return true; + } catch { + return false; + } + } + + /// @notice verify whether a forwarder address is the trustedForwarder address, using the manager setting + /// @dev this function is used to avoid having a trustedForwarder variable inside the splitter + /// @return isTrusted bool whether the forwarder is the trusted address + function _isTrustedForwarder(address forwarder) + internal + view + override(ERC2771HandlerAbstract) + returns (bool isTrusted) + { + return (forwarder == royaltyManager.getTrustedForwarder()); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerAbstract) + returns (address sender) + { + return ERC2771HandlerAbstract._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerAbstract) + returns (bytes calldata messageData) + { + return ERC2771HandlerAbstract._msgData(); + } +} diff --git a/packages/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol b/packages/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol new file mode 100644 index 0000000000..a5f667d8b8 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +///@title IERC20Approve +///@notice Interface for ERC20 token approval operations +interface IERC20Approve { + ///@notice Approves the specified spender to spend up to the given amount of tokens on behalf of the sender + ///@param spender The address that is allowed to spend tokens + ///@param amount The maximum amount of tokens that the spender is allowed to spend + ///@return `true` if the approval was successful, otherwise `false` + function approve(address spender, uint256 amount) external returns (bool); + + ///@notice Increases the allowance granted to the specified spender by the given amount + ///@param spender The address that is allowed to spend tokens + ///@param amount The additional amount of tokens that the spender is allowed to spend + ///@return `true` if the increase in allowance was successful, otherwise `false` + function increaseAllowance(address spender, uint256 amount) external returns (bool); +} diff --git a/packages/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol b/packages/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol new file mode 100644 index 0000000000..760894bba0 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {IMultiRoyaltyRecipients} from "./IMultiRoyaltyRecipients.sol"; +import {Recipient} from "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol"; + +///Multi-receiver EIP2981 reference override implementation +interface IMultiRoyaltyDistributor is IERC165, IMultiRoyaltyRecipients { + event TokenRoyaltyRemoved(uint256 tokenId); + event DefaultRoyaltyBpsSet(uint16 royaltyBPS); + + event DefaultRoyaltyReceiverSet(address indexed recipient); + + event RoyaltyRecipientSet(address indexed splitter, address indexed recipient); + + event TokenRoyaltySplitterSet(uint256 tokenId, address splitterAddress); + + event RoyaltyManagerSet(address indexed _royaltyManager); + + struct TokenRoyaltyConfig { + uint256 tokenId; + uint16 royaltyBPS; + Recipient[] recipients; + } + + ///@notice Set per token royalties. Passing a recipient of address(0) will delete any existing configuration + ///@param tokenId The ID of the token for which to set the royalties. + ///@param recipient The address that will receive the royalties. + ///@param creator The creator's address for the token. + function setTokenRoyalties( + uint256 tokenId, + address payable recipient, + address creator + ) external; + + ///@notice Helper function to get all splits contracts + ///@return an array of royalty receiver + function getAllSplits() external view returns (address payable[] memory); +} diff --git a/packages/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol b/packages/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol new file mode 100644 index 0000000000..a6f788df99 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {Recipient} from "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol"; + +/// Multi-receiver EIP2981 implementation +interface IMultiRoyaltyRecipients is IERC165 { + /// @dev Helper function to get all recipients + function getRecipients(uint256 tokenId) external view returns (Recipient[] memory); +} diff --git a/packages/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol b/packages/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol new file mode 100644 index 0000000000..6e45f0d14c --- /dev/null +++ b/packages/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Recipient} from "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol"; + +/// @title IRoyaltyManager +/// @notice interface for RoyaltyManager Contract +interface IRoyaltyManager { + event RecipientSet(address indexed commonRecipient); + + event SplitSet(uint16 commonSplit); + + event RoyaltySet(uint16 royaltyBps, address indexed contractAddress); + + event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder); + + event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress); + + ///@notice sets the common recipient + ///@param _commonRecipient is the common recipient for all the splitters + function setRecipient(address payable _commonRecipient) external; + + ///@notice sets the common split + ///@param commonSplit split for the common recipient + function setSplit(uint16 commonSplit) external; + + ///@notice to be called by the splitters to get the common recipient and split + ///@return recipient which has the common recipient and split + function getCommonRecipient() external view returns (Recipient memory recipient); + + ///@notice returns the amount of basis points allocated to the creator + ///@return creatorSplit the share of creator in bps + function getCreatorSplit() external view returns (uint16 creatorSplit); + + ///@notice returns the commonRecipient and EIP2981 royalty split + ///@return recipient address of common royalty recipient + ///@return royaltySplit contract EIP2981 royalty bps + function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit); + + ///@notice deploys splitter for creator + ///@param creator the address of the creator + ///@param recipient the wallet of the recipient where they would receive their royalty + ///@return creatorSplitterAddress splitter's address deployed for creator + function deploySplitter(address creator, address payable recipient) + external + returns (address payable creatorSplitterAddress); + + ///@notice returns the address of splitter of a creator. + ///@param creator the address of the creator + ///@return creatorSplitterAddress splitter's address deployed for a creator + function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress); + + ///@notice returns the EIP2981 royalty split + ///@param _contractAddress the address of the contract for which the royalty is required + ///@return royaltyBps royalty bps of the contract + function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps); + + ///@notice sets the trustedForwarder address to be used by the splitters + ///@param _newForwarder is the new trusted forwarder address + function setTrustedForwarder(address _newForwarder) external; + + ///@notice get the current trustedForwarder address + ///@return trustedForwarder address of current trusted Forwarder + function getTrustedForwarder() external view returns (address trustedForwarder); +} diff --git a/packages/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol b/packages/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol new file mode 100644 index 0000000000..9344fd554d --- /dev/null +++ b/packages/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol @@ -0,0 +1,11 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IRoyaltyUGC +/// @notice interface define function for managing creator of UGC (User-Generated Content) +interface IRoyaltyUGC { + ///@notice Gets the address of the creator associated with a specific token. + ///@param tokenId the Id of token to retrieve the creator address for + ///@return creator the address of creator + function getCreatorAddress(uint256 tokenId) external pure returns (address creator); +} diff --git a/packages/dependency-royalty-management/contracts/mock/FallbackRegistry.sol b/packages/dependency-royalty-management/contracts/mock/FallbackRegistry.sol new file mode 100644 index 0000000000..01680e3e73 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/FallbackRegistry.sol @@ -0,0 +1,3 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {FallbackRegistry} from "@manifoldxyz/royalty-registry-solidity/contracts/FallbackRegistry.sol"; diff --git a/packages/dependency-royalty-management/contracts/mock/MockMarketplace.sol b/packages/dependency-royalty-management/contracts/mock/MockMarketplace.sol new file mode 100644 index 0000000000..e91b1d7299 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/MockMarketplace.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC2981} from "@openzeppelin/contracts/interfaces/IERC2981.sol"; +import {IERC1155} from "@openzeppelin/contracts/interfaces/IERC1155.sol"; +import {IERC721} from "@openzeppelin/contracts/interfaces/IERC721.sol"; +import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol"; +import {IRoyaltyEngineV1} from "@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyEngineV1.sol"; + +contract MockMarketplace { + IRoyaltyEngineV1 public royaltyEngine; + + constructor(address _royaltyEngine) { + royaltyEngine = IRoyaltyEngineV1(_royaltyEngine); + } + + function distributeRoyaltyEIP2981( + uint256 erc20TokenAmount, + IERC20 erc20Contract, + address nftContract, + uint256 nftId, + address nftBuyer, + address nftSeller, + bool is1155 + ) external payable { + if (msg.value == 0) { + require(erc20TokenAmount > 0, "erc20 token ammount can't be zero"); + (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, erc20TokenAmount); + erc20Contract.transferFrom(nftBuyer, royaltyReceiver, value); + erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - value)); + } else { + (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, msg.value); + (bool sent, ) = royaltyReceiver.call{value: value}(""); + require(sent, "Failed to send distributeRoyaltyEIP2981Ether"); + (bool sentToSeller, ) = nftSeller.call{value: msg.value - value}(""); + require(sentToSeller, "Failed to send to seller"); + } + if (is1155) { + IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, "0x"); + } else { + IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, "0x"); + } + } + + function distributeRoyaltyRoyaltyEngine( + uint256 erc20TokenAmount, + IERC20 erc20Contract, + address nftContract, + uint256 nftId, + address nftBuyer, + address nftSeller, + bool is1155 + ) external payable { + if (msg.value == 0) { + require(erc20TokenAmount > 0, "erc20 token ammount can't be zero"); + uint256 TotalRoyalty; + (address payable[] memory recipients, uint256[] memory amounts) = + royaltyEngine.getRoyalty(address(nftContract), nftId, erc20TokenAmount); + for (uint256 i; i < recipients.length; i++) { + erc20Contract.transferFrom(nftBuyer, recipients[i], amounts[i]); + TotalRoyalty += amounts[i]; + } + erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - TotalRoyalty)); + } else { + (address payable[] memory recipients, uint256[] memory amounts) = + royaltyEngine.getRoyalty(address(nftContract), nftId, msg.value); + uint256 TotalRoyalty; + for (uint256 i; i < recipients.length; i++) { + (bool sent, ) = recipients[i].call{value: amounts[i]}(""); + require(sent, "Failed to send Ether"); + TotalRoyalty += amounts[i]; + } + (bool sentToSeller, ) = nftSeller.call{value: msg.value - TotalRoyalty}(""); + require(sentToSeller, "Failed to send to seller"); + } + if (is1155) { + IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, "0x"); + } else { + IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, "0x"); + } + } +} diff --git a/packages/dependency-royalty-management/contracts/mock/MockTrustedForwarder.sol b/packages/dependency-royalty-management/contracts/mock/MockTrustedForwarder.sol new file mode 100644 index 0000000000..857dd27681 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/MockTrustedForwarder.sol @@ -0,0 +1,3 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {MockTrustedForwarder} from "@sandbox-smart-contracts/dependency-metatx/contracts/test/MockTrustedForwarder.sol"; diff --git a/packages/dependency-royalty-management/contracts/mock/NFTWithoutTransferCheck.sol b/packages/dependency-royalty-management/contracts/mock/NFTWithoutTransferCheck.sol new file mode 100644 index 0000000000..2a19b65554 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/NFTWithoutTransferCheck.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +contract NFTWithoutTransferCheck { + // Mapping from token ID to account balances + mapping(uint256 => mapping(address => uint256)) public _balances; + + // Mapping from account to operator approvals + mapping(address => mapping(address => bool)) private _operatorApprovals; + + function mint( + address to, + uint256 id, + uint256 amount + ) external { + _balances[id][to] = amount; + } + + function transfer( + address from, + address to, + uint256 id, + uint256 amount + ) external { + _balances[id][from] -= amount; + _balances[id][to] += amount; + } + + function balanceOf(address owner, uint256 id) external view returns (uint256 amount) { + return _balances[id][owner]; + } +} diff --git a/packages/dependency-royalty-management/contracts/mock/OverflowERC20.sol b/packages/dependency-royalty-management/contracts/mock/OverflowERC20.sol new file mode 100644 index 0000000000..729c072da9 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/OverflowERC20.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity ^0.8.0; + +contract OverflowTestERC20 { + uint256 constant MAX_BALANCE = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + mapping(address => uint256) private balances; + + function mintMax(address account) external { + balances[account] = MAX_BALANCE; + } + + function balanceOf(address _account) external view returns (uint256) { + return balances[_account]; + } +} diff --git a/packages/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol b/packages/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol new file mode 100644 index 0000000000..e8899866ea --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol @@ -0,0 +1,3 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {RoyaltyEngineV1} from "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyEngineV1.sol"; diff --git a/packages/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol b/packages/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol new file mode 100644 index 0000000000..180ad30da3 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol @@ -0,0 +1,3 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import {RoyaltyRegistry} from "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyRegistry.sol"; diff --git a/packages/dependency-royalty-management/contracts/mock/SingleReceiver.sol b/packages/dependency-royalty-management/contracts/mock/SingleReceiver.sol new file mode 100644 index 0000000000..bcfc5f1803 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/SingleReceiver.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { + ERC1155Upgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; +import {RoyaltyDistributor} from "../RoyaltyDistributor.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; + +contract SingleReceiver is ERC1155Upgradeable, RoyaltyDistributor, ERC2771HandlerUpgradeable { + /// @notice initiliaze to be called by the proxy + /// @dev would run once. + /// @param _manager, the address of the Manager contract for common royalty recipient + function initialize(address _manager, address trustedForwarder) external initializer { + __RoyaltyDistributor_init(_manager); + __ERC2771Handler_init(trustedForwarder); + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(ERC1155Upgradeable, RoyaltyDistributor) + returns (bool) + { + return ERC1155Upgradeable.supportsInterface(interfaceId) || RoyaltyDistributor.supportsInterface(interfaceId); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } +} diff --git a/packages/dependency-royalty-management/contracts/mock/TestERC1155.sol b/packages/dependency-royalty-management/contracts/mock/TestERC1155.sol new file mode 100644 index 0000000000..d987fb2f29 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/TestERC1155.sol @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { + ERC1155Upgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {MultiRoyaltyDistributor} from "../MultiRoyaltyDistributor.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; + +/// @title Test ERC1155 contract +/// @dev Made to test splitter deployment for each creator +/// Creator could change his royalty receiving Wallet for his splitter through setRoyaltyRecipient function +contract TestERC1155 is ERC1155Upgradeable, OwnableUpgradeable, MultiRoyaltyDistributor, ERC2771HandlerUpgradeable { + /// @notice initiliaze to be called by the proxy + /// @dev would run once. + /// @param _manager, the address of the Manager contract for common royalty recipient + function initialize(address _manager, address trustedForwarder) external initializer { + __MultiRoyaltyDistributor_init(_manager); + __Ownable_init(); + __ERC2771Handler_init(trustedForwarder); + } + + /// @notice function to mint a single ERC1155 token + /// @param to address of the token owner + /// @param id of the token + /// @param amount of the token to be minted + /// @param royaltyRecipient the royalty recipient for the creator + /// @param data for miniting + function mint( + address to, + uint256 id, + uint256 amount, + address payable royaltyRecipient, + bytes memory data + ) external { + _mint(to, id, amount, data); + _setTokenRoyalties(id, royaltyRecipient, msg.sender); + } + + /// @notice function to mint a batch ERC1155 token + /// @param to address of the token owner + /// @param ids array of ids the tokens + /// @param amounts array of the amounts of tokens to be minted. + /// @param royaltyRecipient the royalty recipient for the creator + /// @param data for miniting + function mintBatch( + address to, + uint256[] memory ids, + uint256[] memory amounts, + address payable royaltyRecipient, + bytes memory data + ) external { + _mintBatch(to, ids, amounts, data); + for (uint256 i; i < ids.length; i++) { + _setTokenRoyalties(ids[i], royaltyRecipient, msg.sender); + } + } + + /// @notice EIP 165 interface funtion + /// @dev used to check interface implemented + /// @param interfaceId to be checked for implementation + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(MultiRoyaltyDistributor, ERC1155Upgradeable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + /// @notice Not in our use case + /// @dev Explain to a developer any extra details + /// @param tokenId a parameter just like in doxygen (must be followed by parameter name) + /// @param recipient the royalty recipient for the splitter of the creator. + /// @param creator the creactor of the tokens. + function setTokenRoyalties( + uint256 tokenId, + address payable recipient, + address creator + ) external override onlyOwner { + _setTokenRoyalties(tokenId, recipient, creator); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } +} diff --git a/packages/dependency-royalty-management/contracts/mock/TestERC20.sol b/packages/dependency-royalty-management/contracts/mock/TestERC20.sol new file mode 100644 index 0000000000..329d2ccc14 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/TestERC20.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +/* solhint-disable-next-line no-empty-blocks*/ + +pragma solidity ^0.8.0; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract TestERC20 is ERC20 { + /* solhint-disable-next-line no-empty-blocks*/ + constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {} + + function mint(address account, uint256 amount) external { + _mint(account, amount); + } +} diff --git a/packages/dependency-royalty-management/contracts/mock/TestERC721.sol b/packages/dependency-royalty-management/contracts/mock/TestERC721.sol new file mode 100644 index 0000000000..817b944ca8 --- /dev/null +++ b/packages/dependency-royalty-management/contracts/mock/TestERC721.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import { + ERC721Upgradeable, + ContextUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {MultiRoyaltyDistributor} from "../MultiRoyaltyDistributor.sol"; +import { + ERC2771HandlerUpgradeable +} from "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol"; + +contract TestERC721 is ERC721Upgradeable, OwnableUpgradeable, MultiRoyaltyDistributor, ERC2771HandlerUpgradeable { + /// @notice initiliaze to be called by the proxy + /// @dev would run once. + /// @param _manager, the address of the Manager contract for common royalty recipient + function initialize(address _manager, address trustedForwarder) external initializer { + __MultiRoyaltyDistributor_init(_manager); + __Ownable_init(); + __ERC2771Handler_init(trustedForwarder); + } + + /// @notice function to mint a single ERC721 token + /// @param to address of the token owner + /// @param id of the token + /// @param royaltyRecipient the royalty recipient for the creator + function mint( + address to, + uint256 id, + address payable royaltyRecipient + ) external { + _mint(to, id); + _setTokenRoyalties(id, royaltyRecipient, msg.sender); + } + + /// @notice function to mint a batch ERC721 token + /// @param to address of the token owner + /// @param ids array of ids the tokens + /// @param royaltyRecipient the royalty recipient for the creator + function mintBatch( + address to, + uint256[] memory ids, + address payable royaltyRecipient + ) external { + for (uint256 i; i < ids.length; i++) { + _mint(to, ids[i]); + _setTokenRoyalties(ids[i], royaltyRecipient, msg.sender); + } + } + + /// @notice EIP 165 interface funtion + /// @dev used to check interface implemented + /// @param interfaceId to be checked for implementation + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(MultiRoyaltyDistributor, ERC721Upgradeable) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + /// @notice Not in our use case + /// @dev Explain to a developer any extra details + /// @param tokenId a parameter just like in doxygen (must be followed by parameter name) + /// @param recipient the royalty recipient for the splitter of the creator. + /// @param creator the creactor of the tokens. + function setTokenRoyalties( + uint256 tokenId, + address payable recipient, + address creator + ) external override onlyOwner { + _setTokenRoyalties(tokenId, recipient, creator); + } + + function _msgSender() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (address sender) + { + return ERC2771HandlerUpgradeable._msgSender(); + } + + function _msgData() + internal + view + virtual + override(ContextUpgradeable, ERC2771HandlerUpgradeable) + returns (bytes calldata) + { + return ERC2771HandlerUpgradeable._msgData(); + } +} diff --git a/packages/dependency-royalty-management/docs/MultiRoyaltyDistributer.md b/packages/dependency-royalty-management/docs/MultiRoyaltyDistributer.md new file mode 100644 index 0000000000..6d3df521bb --- /dev/null +++ b/packages/dependency-royalty-management/docs/MultiRoyaltyDistributer.md @@ -0,0 +1,155 @@ +# MultiRoyaltyDistributer + +MultiRoyaltyDistributer contract that implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. Specifically, it provides functionality for managing royalties for a collection of NFT tokens, where royalties are paid to multiple recipients + +The NFT token contract which would import this contract could deploy RoyaltySplitter contract to split EIP2981 creatorRoyalty between the creator and the commonRecipient in the RoyaltyManager contract. This contract would call the RoyaltyManager contract to deploy the splitter. + +The creator would have a single splitter which would receive the EIP2981 royalty from marketplaces which distribute EIP2981 Royalty. For the market place which distribute royalty through RoyaltyEngineV1 contract of manifolds,The royalty is directly split and send to creator as well as the commonRecipient. + +For more information on how the royalty could be distributed please read RoyaltySplitter.md. + +## External functions + +--- + +```Solidity + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(ERC165, IERC165) returns (bool) +``` + +- EIP 165 interface function called to check which interfaces are implemented on MultiRoyaltyDistributer contract. +- The function overrides the supportsInterface function defined in the `ERC165` and `IERC165` contracts. It first checks if the interfaceId matches the interfaceId of the `IEIP2981`, `IEIP2981MultiReceiverRoyaltyOverride` and `IERC165` interfaces, and returns true if there is a match. + +- `interfaceId`: interfaceId to be checked for implementation + +--- + +```Solidity + function getTokenRoyalties() + external + view + override + returns (TokenRoyaltyConfig[] memory royaltyConfigs) +``` + +- This function return that returns an array which contain Token Royalty info of type `TokenRoyaltyConfig` struct. The royalty config would be Tokens which have splitter deployed for them. +- The `TokenRoyaltyConfig `struct has two fields: +- `tokenId (uint256):` the ID of the token +- `recipients` `(address[])`: an array of addresses representing the recipients of royalties for the token, Which has receiver Wallet and there Bps splits of the Royalty amount. + +--- + +```Solidity + function royaltyInfo( + uint256 tokenId, + uint256 value + ) public view override returns (address, uint256) +``` + +- Gets the address of the royalty splitter and the royalty value for a given token. +- `tokenId`: The ID of the token for which to get royalty information. +- `value`: The Amount on which the royalty has to be calculated. +- `returns`: The address of the splitter for the token if deployed else the default royalty recipient and EIP2981 royalty amount. + +--- + +```Solidity + function getAllSplits() + external + view + override + returns (address payable[] memory splits) +``` + +- function used to get all the royalty recipient for Token royalty on this contract Based on EIP2981. It allows querying all the royalty splitter contracts associated with all tokens that have royalties set, as well as the default royalty recipient. +- `return` array of address of all the royalty splitter contracts associated with all tokens that have royalties set, as well as the default royalty recipient if it exists. + +--- + +```Solidity + function getRecipients( + uint256 tokenId + ) public view returns (Recipient[] memory) +``` + +- This function used to gets the royalty recipients for the given token Id, i.e creator wallet address and his split in Bps of total Royalty amount also commonRecipient on RoyaltyManager contract and his split in Bps of Total royalty amount. Otherwise the total default royalty receiver and Total_BASIS_POINTS for full split of total Royalty amount. +- `tokenId`: uint256 ID of the token to get the royalty recipients. +- `return` An array of Recipient structs representing the royalty recipients. + +--- + +```Solidity + function _setTokenRoyalties( + uint256 tokenId, + address payable recipient, + address creator + ) internal +``` + +- Sets the royalty for a given token +- `tokenId`: The ID of the token +- `recipient`: The address that will receive the royalties +- `creator`: The address of the creator of the token + +--- + +## Events + +Events that are emitted through the lifetime of the contract + +--- + +```Solidity + event TokenRoyaltySet( + uint256 tokenId, + uint16 royaltyBPS, + address Recipient + ); +``` + +- Event emitted when token Royalty is set. +- emitted when \_setTokenRoyalties is called. +- `tokenId`: The id of the token. +- `royaltyBPS`: The EIP2981 royalty base points for royalty amount. +- `Recipient`: The EIP2981 recipient of the royalty + +--- + +--- + +```Solidity + event DefaultRoyaltyBpsSet(uint16 royaltyBPS); + +``` + +- Event emitted when default Royalty Bps is set. +- emitted when \_setDefaultRoyaltyBps is called. +- `royaltyBPS`: The new default royalty base point for EIP2981 royalty. + +--- + +--- + +```Solidity + event DefaultRoyaltyReceiverSet(address recipient); + +``` + +- Event emitted when default Royalty receiver is set. +- emitted when \_setDefaultRoyaltyReceiver is called. +- `recipient`: The new default royalty recipient for EIP2981 royalty. + +--- + +--- + +```Solidity + event RoyaltyRecipientSet(address splitter, address recipient); +``` + +- Event emitted when Royalty receiver for a creator is is set on there splitter. +- emitted when \_setRoyaltyRecipient is called. +- `recipient`: The new royalty recipient for the creator share of the Total EIP2981 royalty. + +--- diff --git a/packages/dependency-royalty-management/docs/RoyaltyDistributer.md b/packages/dependency-royalty-management/docs/RoyaltyDistributer.md new file mode 100644 index 0000000000..b4b7cbe636 --- /dev/null +++ b/packages/dependency-royalty-management/docs/RoyaltyDistributer.md @@ -0,0 +1,35 @@ +# RoyaltyDistributer + +Contract to get common royalty recipient and the EIP2981 royalties BPS from the RoyaltyManager contract. + +## External functions + +--- + +```Solidity + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(ERC165, IERC165) returns (bool) +``` + +- The function overrides the supportsInterface function defined in the `ERC165` and `IERC165` contracts. It first checks if the interfaceId matches the interfaceId of the `IEIP2981` and `IERC165` interfaces, and returns true if there is a match. + +- `interfaceId`: interfaceId to be checked for implementation + +--- + +```Solidity + function royaltyInfo(uint256 _tokenId, uint256 _salePrice) + external + view + returns (address receiver, uint256 royaltyAmount) +``` + +- This is ERC2981 royaltyInfo function. +- `tokenId` : the id of token for which the royalty is to be calculated. +- `_salePrice` : the price of the token. +- returns `receiver` : receiver of the royalty (i.e. common recipient from RoyaltyManager) +- returns `royaltyAmount` : royalty amount to be sent. + +--- + diff --git a/packages/dependency-royalty-management/docs/RoyaltyManager.md b/packages/dependency-royalty-management/docs/RoyaltyManager.md new file mode 100644 index 0000000000..d0067866ca --- /dev/null +++ b/packages/dependency-royalty-management/docs/RoyaltyManager.md @@ -0,0 +1,202 @@ +# RoyaltyManager + +RoyaltyManager contract stores the common royalty recipient so the RoyaltySplitters can read it. it also stores the royalty split for the common royalty RoyaltySplitter so that the EIP2981 Royalty is divided between the creator and the common royalty recipient. + +Common recipient gets commonSplit/Total_Total_Base_Points part of the royalty and creator get (Total_Total_Base_Points - commonSplit)/Total_Total_Base_Points part of the royalty. + +This contract also stores the EIP2981 RoyaltyBps for the contact's which don't use RoyaltySplitters for royalty distribution. + +This contract also deploys the RoyaltySplitters for creators, which are deployed when the called by the NFT contracts. A single RoyaltySplitter would be deployed for a creator and these RoyaltySplitters are deployed through RoyaltyManager so that they could be shared across various NFT contracts to receive royalty for a creator. + +## External functions + +```Solidity + function initialize( + address payable _commonRecipient, + uint16 _commonSplit, + address royaltySplitterCloneable, + address managerAdmin, + address contractRoyaltySetter + ) external initializer +``` + +- Initialization function for deploying the contract via a proxy +- This function is called during deployment and sets the common recipient and split for all the RoyaltySplitters. +- ` _commonRecipient`: The common recipient wallet address for all the RoyaltySplitters +- `_commonSplit` The split percentage for the common recipient and creators split would be 10000 - commonSplit +- `royaltySplitterCloneable` address of cloneable splitter contract for royalties distribution +- `managerAdmin` address of RoyaltyManager contract. +- `contractRoyaltySetter` the address of royalty setter of contract. + +--- + +```Solidity + function setSplit( + uint16 _commonSplit + ) external override onlyRole(DEFAULT_ADMIN_ROLE) +``` + +- Sets the common split Bps for the common recipient +- `_commonSplit`: The new common split percentage to be set +- emits `RecipientSet` event. + +--- + +```Solidity + function setContractRoyalty( + address contractAddress, + uint16 _royaltyBps + ) external onlyRole(CONTRACT_ROYALTY_SETTER_ROLE) +``` + +- This function sets the royalty split percentage for a specific contract according to the EIP 2981 standard. +- `contractAddress`: The address of the contract for which the royalty split percentage is being set +- `_royaltyBps`: The new royalty split percentage to be set for the specified contract +- Emits `RoyaltySet` event. + +--- + +```Solidity + function getCommonRecipient() + external + view + override + returns (Recipient memory recipient) +``` + +- This function returns the common recipient and split to be used by the RoyaltySplitters +- return `recipient` A Recipient struct containing the common recipient and split information. + +--- + +```Solidity +function setRecipient( + address payable _commonRecipient + ) external override onlyRole(DEFAULT_ADMIN_ROLE) +``` + +- Sets the common recipient wallet address for all the RoyaltySplitters +- This function can only be called by the contract owner (or later by a RoyaltyManager) +- `_commonRecipient`: The new common recipient wallet address to be set + +--- + +```Solidity +function deployRoyaltySplitter( + address creator, + address payable recipient + ) external returns (address payable) +``` + +- deploys the RoyaltySplitter for a creator +- This function should be called by the token contracts +- `creator`: the address of the creator +- `recipient` : the wallet of the recipient where they would receive there royalty +- returns `creatorRoyaltySplitterAddress` : deployed for a creator + +--- + +```Solidity +function getCreatorRoyaltySplitter( + address creator + ) external view returns (address payable) +``` + +- This function returns the the address of RoyaltySplitter of a creator. +- `creator` the address of the creator +- returns the RoyaltySplitter of the creator. + +--- + +```Solidity +function getCreatorSplit() external view returns (uint16) +``` + +- This function returns the creator split to be used by the RoyaltySplitters +- return `creatorSplit` An unsigned integer representing the creator split + +--- + +```Solidity +function getRoyaltyInfo() external view returns (address, uint16) +``` + +- This function returns the common recipient and EIP2981 royalty split for the caller contract +- External function to retrieve information on the common recipient and EIP2981 royalty split for a given contract +- returns EIP-2981 royalty receiver and royalty BPS + +--- + +```Solidity + function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) +``` + +- This function returns EIP2981 RoyaltyBPS for a contract +- `_contractAddress` address of the contract for the royalty has to be retrieved. + +--- + +```Solidity + function _setRecipient( + address payable _commonRecipient + ) internal +``` + +- This function sets the common recipient for all the RoyaltySplitters +- `_commonRecipient`: the common recipient for all the RoyaltySplitters +- emits `RecipientSet` event. + +--- + +```Solidity + function _setSplit( + uint16 _commonSplit + ) internal +``` + +- This function sets the common recipient and common split +- `_commonSplit`: split for the common recipient and creators split would be 10000 - `_commonSplit` +- emits `SplitSet` event. + +--- + +## Events + +Events that are emitted through the lifetime of the contract + +--- + +```Solidity + event RecipientSet(address commonRecipient); +``` + +- Event emitted when common recipient is set. +- emitted when \_setRecipient is called. +- `commonRecipient`: The wallet address of the commonRecipient. + +--- + +--- + +```Solidity + event SplitSet(uint16 commonSplit); +``` + +- Event emitted when common split is set. +- emitted when \_setSplit is called. +- `commonSplit`: The common recipients split of royalty in bps. + +--- + +--- + +```Solidity + event RoyaltySet(uint16 royaltyBps, address contractAddress); +``` + +- Event emitted when EIP2981 Royalty bps is set for a contract. +- emitted when setContractRoyalty is called. +- `royaltyBps`: Royalty Bps. +- `contractAddress`: Contract address for which the royalty is set. + +--- diff --git a/packages/dependency-royalty-management/docs/RoyaltySplitter.md b/packages/dependency-royalty-management/docs/RoyaltySplitter.md new file mode 100644 index 0000000000..2a5b665c35 --- /dev/null +++ b/packages/dependency-royalty-management/docs/RoyaltySplitter.md @@ -0,0 +1,91 @@ +# RoyaltySplitter + +Implementing a clone-able and configurable royalty splitter. It allows for the distribution of royalties from NFT sales among 2 recipients. First recipient is the creator's wallet and the second recipient is common recipient in the RoyaltyManager contract. + +This contract calls the RoyaltyManager contract for the common recipient's address, common recipient's split of the Royalty and creator's split of the royalty. Just the creators wallet address is set here to send the royalty RoyaltySplitter's owner is the RoyaltyManager contract. + +## functions + +```Solidity + function initialize( + address payable recipient, + address manager + ) public initializer +``` + +- Initializes the contract after its initial deployment by setting the recipient wallet address and royalty manager contract's addresses +- `recipient`: The address of the recipient of the funds +- `manager`: The address of the manager contract + +--- + +```Solidity + function setRecipients( + Recipient[] calldata recipients + ) external override onlyOwner +``` + +- This function used to set the recipients wallet address. but not the split. This is done to be in compliance with the splitter interface of manifolds. +- `recipients`: The array of recipients which should only have one recipient to be set. + +--- + +```Solidity + function getRecipients() + external + view + override + returns (Recipient[] memory) +``` + +- Retrieves an array of recipients of the royalties sent to this contract +- `return` An array of Recipient , each containing Recipient address and a BPS value representing the share of the royalties they receive in Recipient address. + +--- + +```Solidity + function splitETH() public +``` + +- Allows any ETH stored by the contract to be split among recipients +- Normally ETH is forwarded as it comes. +- Could only be called by the one of the recipient(creator or common recipient) + +--- + +```Solidity +function splitERC20Tokens(IERC20 erc20Contract) public +``` + +- This function allows recipients to split all available ERC20 at the provided address between the recipients +- recipients(both creator and common) can only call this function to split all available tokens recipients. +- `erc20Contract`: The ERC20 token contract to split + +--- + +## Events + +```Solidity + event ETHTransferred(address indexed account, uint256 amount) +``` + +- Emitted when ETH is transferred +- `account` The address of the account that transferred the ETH +- `amount` The amount of ETH transferred + +--- + +```Solidity + event ERC20Transferred( + address indexed erc20Contract, + address indexed account, + uint256 amount + ); +``` + +- Emitted when an ERC20 token transfer occurs +- `erc20Contract`: The address of the ERC20 contract that emitted the event. +- `account`: The address of the account that transferred the tokens +- `amount`: The amount of tokens transferred + +--- diff --git a/packages/dependency-royalty-management/hardhat.config.ts b/packages/dependency-royalty-management/hardhat.config.ts new file mode 100644 index 0000000000..a62676034f --- /dev/null +++ b/packages/dependency-royalty-management/hardhat.config.ts @@ -0,0 +1,23 @@ +import '@nomicfoundation/hardhat-toolbox'; +import {HardhatUserConfig} from 'hardhat/config'; +import 'solidity-coverage'; +import '@openzeppelin/hardhat-upgrades'; + +const config: HardhatUserConfig = { + // solidity compiler version may be updated for new packages as required + // to ensure packages use up-to-date dependencies + solidity: { + compilers: [ + { + version: '0.8.18', + settings: { + optimizer: { + enabled: true, + runs: 2000, + }, + }, + }, + ], + }, +}; +export default config; diff --git a/packages/dependency-royalty-management/package.json b/packages/dependency-royalty-management/package.json new file mode 100644 index 0000000000..a3a139b853 --- /dev/null +++ b/packages/dependency-royalty-management/package.json @@ -0,0 +1,64 @@ +{ + "name": "@sandbox-smart-contracts/dependency-royalty-management", + "version": "0.0.1", + "description": "The Sandbox Royalty Implementation", + "files": [ + "contracts" + ], + "scripts": { + "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && solhint --max-warnings 0 \"contracts/**/*.sol\"", + "lint:fix": "eslint --fix \"**/*.{js,ts}\" && solhint --fix \"contracts/**/*.sol\"", + "format": "prettier --check \"**/*.{ts,js,sol}\"", + "format:fix": "prettier --write \"**/*.{ts,js,sol}\"", + "test": "hardhat test", + "coverage": "hardhat coverage --testfiles 'test/*.ts''test/*.js'", + "hardhat": "hardhat", + "compile": "hardhat compile" + }, + "mocha": { + "require": "hardhat/register", + "timeout": 40000, + "_": [ + "test/**/*.ts" + ] + }, + "devDependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@manifoldxyz/libraries-solidity": "^1.0.4", + "@manifoldxyz/royalty-registry-solidity": "^2.0.3", + "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", + "@nomicfoundation/hardhat-network-helpers": "^1.0.0", + "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", + "@nomiclabs/hardhat-etherscan": "^3.1.7", + "@openzeppelin/contracts": "^4.9.0", + "@openzeppelin/contracts-upgradeable": "^4.9.0", + "@openzeppelin/hardhat-upgrades": "^1.28.0", + "@sandbox-smart-contracts/dependency-metatx": "*", + "@typechain/ethers-v5": "^10.2.1", + "@typechain/hardhat": "^6.1.6", + "@types/chai": "^4.3.5", + "@types/mocha": "^10.0.1", + "@types/node": "^20.1.2", + "@typescript-eslint/eslint-plugin": "^5.59.8", + "@typescript-eslint/parser": "^5.59.8", + "chai": "^4.3.7", + "dotenv": "^16.1.4", + "eslint": "^8.41.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-mocha": "^10.1.0", + "eslint-plugin-prettier": "^4.2.1", + "ethers": "^5.7.2", + "hardhat": "^2.14.1", + "hardhat-gas-reporter": "^1.0.9", + "prettier": "^2.8.8", + "prettier-plugin-solidity": "1.0.0-beta.11", + "solhint": "^3.4.1", + "solhint-plugin-prettier": "^0.0.5", + "solidity-coverage": "^0.8.2", + "ts-node": "^10.9.1", + "typechain": "^8.1.1", + "typescript": "^5.0.4" + } +} diff --git a/packages/dependency-royalty-management/test/RoyaltyDistribution.test.ts b/packages/dependency-royalty-management/test/RoyaltyDistribution.test.ts new file mode 100644 index 0000000000..831b01b14d --- /dev/null +++ b/packages/dependency-royalty-management/test/RoyaltyDistribution.test.ts @@ -0,0 +1,2248 @@ +import {ethers} from 'hardhat'; +import {expect} from 'chai'; +import {splitterAbi} from './Splitter.abi'; +import {royaltyDistribution} from './fixture'; +import {BigNumber} from 'ethers'; +const zeroAddress = '0x0000000000000000000000000000000000000000'; + +describe('Royalty', function () { + describe('Royalty distribution through splitter', function () { + it('should emit TrustedForwarderSet event with correct data when setting new trusted forwarder', async function () { + const { + deployer, + RoyaltyManagerContract, + RoyaltyManagerAsAdmin, + TrustedForwarder, + } = await royaltyDistribution(); + expect( + await await RoyaltyManagerContract.getTrustedForwarder() + ).to.be.equal(TrustedForwarder.address); + await expect(RoyaltyManagerAsAdmin.setTrustedForwarder(deployer.address)) + .to.emit(RoyaltyManagerContract, 'TrustedForwarderSet') + .withArgs(TrustedForwarder.address, deployer.address); + }); + + it('should emit SplitterDeployed event with correct data when deploying splitter', async function () { + const { + seller, + royaltyReceiver, + RoyaltyManagerContract, + RoyaltyManagerAsAdmin, + splitterDeployerRole, + } = await royaltyDistribution(); + + expect( + await RoyaltyManagerContract.creatorRoyaltiesSplitter(seller.address) + ).to.be.equals('0x0000000000000000000000000000000000000000'); + await RoyaltyManagerAsAdmin.grantRole( + splitterDeployerRole, + seller.address + ); + + const splitterDeployedTx = await RoyaltyManagerContract.connect( + seller + ).deploySplitter(seller.address, royaltyReceiver.address); + + await expect(splitterDeployedTx) + .to.emit(RoyaltyManagerContract, 'SplitterDeployed') + .withArgs( + seller.address, + royaltyReceiver.address, + await RoyaltyManagerContract.creatorRoyaltiesSplitter(seller.address) + ); + }); + + it('should split ERC20 using EIP2981', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + ERC1155AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + const balance = await ERC20.balanceOf(splitter); + + expect(balance).to.be.equal(1000000 * (erc1155Royalty / 10000)); + + await splitterContract + .connect(await ethers.getSigner(royaltyReceiver.address)) + .splitERC20Tokens(ERC20.address); + + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + }); + + it('should split ERC20 using EIP2981 using trusted forwarder', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + ERC1155AsSeller, + RoyaltyManagerContract, + TrustedForwarder, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + const balance = await ERC20.balanceOf(splitter); + + expect(balance).to.be.equal(1000000 * (erc1155Royalty / 10000)); + const data = await splitterContract + .connect(royaltyReceiver.address) + .populateTransaction['splitERC20Tokens(address)'](ERC20.address); + + await TrustedForwarder.execute({...data, value: BigNumber.from(0)}); + + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + }); + it('should split ERC20 using RoyaltyEngine', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + RoyaltyRegistry, + ERC1155AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + + await RoyaltyRegistry.connect(deployer).setRoyaltyLookupAddress( + ERC1155.address, + ERC1155.address + ); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + }); + + it('should split ETh using EIP2981', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + user, + ERC1155AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + const balanceRoyaltyReceiver = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + const value = ethers.utils.parseUnits('1000', 'ether'); + await mockMarketplace + .connect(await ethers.getSigner(user.address)) + .distributeRoyaltyEIP2981( + 0, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiverNew = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiverNew.sub(balanceRoyaltyReceiver)).to.be.equal( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + expect( + balanceRoyaltyReceiverNew + .sub(balanceRoyaltyReceiver) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)) + ); + }); + + it('should split ETh using RoyaltyEngine', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + user, + ERC1155AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC1155.connect(seller).setApprovalForAll( + mockMarketplace.address, + true + ); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + const balanceRoyaltyReceiver = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + const value = ethers.utils.parseUnits('1000', 'ether'); + await mockMarketplace + .connect(await ethers.getSigner(user.address)) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiverNew = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiverNew.sub(balanceRoyaltyReceiver)).to.be.equal( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + expect( + balanceRoyaltyReceiverNew + .sub(balanceRoyaltyReceiver) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)) + ); + }); + + it('should receive Royalty in Eth to new address set by the creator', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC1155AsSeller, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + royaltyReceiver2, + user, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + seller.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + expect(await splitterContract.recipient()).to.be.equal( + royaltyReceiver.address + ); + + const tnx = await RoyaltyManagerContract.connect( + seller + ).setRoyaltyRecipient(royaltyReceiver2.address); + + await tnx.wait(); + + expect(await splitterContract.recipient()).to.be.equal( + royaltyReceiver2.address + ); + + const balanceRoyaltyReceiver2 = await ethers.provider.getBalance( + royaltyReceiver2.address + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + const value = ethers.utils.parseUnits('1000', 'ether'); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(await ethers.getSigner(user.address)) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiver2New = await ethers.provider.getBalance( + royaltyReceiver2.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect( + balanceRoyaltyReceiver2New.sub(balanceRoyaltyReceiver2) + ).to.be.equal( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + expect( + balanceRoyaltyReceiver2New + .sub(balanceRoyaltyReceiver2) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)) + ); + }); + + it('should receive Royalty in Eth to new common recipient address set by the admin on registry', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + commonRoyaltyReceiver2, + RoyaltyManagerAsAdmin, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + user, + ERC1155AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver.address + ); + + await RoyaltyManagerAsAdmin.setRecipient(commonRoyaltyReceiver2.address); + + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver2.address + ); + + const balanceRoyaltyReceiver = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver2 = await ethers.provider.getBalance( + commonRoyaltyReceiver2.address + ); + const value = ethers.utils.parseUnits('1000', 'ether'); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(user) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiverNew = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver2New = await ethers.provider.getBalance( + commonRoyaltyReceiver2.address + ); + + expect(balanceRoyaltyReceiverNew.sub(balanceRoyaltyReceiver)).to.be.equal( + balanceCommonRoyaltyReceiver2New.sub(balanceCommonRoyaltyReceiver2) + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + expect( + balanceRoyaltyReceiverNew + .sub(balanceRoyaltyReceiver) + .add( + balanceCommonRoyaltyReceiver2New.sub(balanceCommonRoyaltyReceiver2) + ) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)) + ); + }); + + it('should receive Royalty in Eth with new splits set by the admin on registry', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC1155AsSeller, + RoyaltyManagerAsAdmin, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + user, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + await RoyaltyManagerAsAdmin.setSplit(6000); + const balanceRoyaltyReceiver = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + const value = ethers.utils.parseUnits('1000', 'ether'); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(user) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiverNew = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiverNew = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const TotalRoyalty = value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)); + + const sellerRoyaltyShare = TotalRoyalty.mul( + ethers.BigNumber.from(4000) + ).div(ethers.BigNumber.from(10000)); + + const commonRecipientShare = TotalRoyalty.mul( + ethers.BigNumber.from(6000) + ).div(ethers.BigNumber.from(10000)); + + expect(balanceRoyaltyReceiverNew.sub(balanceRoyaltyReceiver)).to.be.equal( + sellerRoyaltyShare + ); + + expect( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ).to.be.equal(commonRecipientShare); + + expect( + balanceRoyaltyReceiverNew + .sub(balanceRoyaltyReceiver) + .add( + balanceCommonRoyaltyReceiverNew.sub(balanceCommonRoyaltyReceiver) + ) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)) + ); + }); + + it('should receive Royalty(creator) in ERC20 to new address royalty recipient address', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + ERC1155AsSeller, + RoyaltyManagerContract, + royaltyReceiver2, + } = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + seller.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + expect(await splitterContract.recipient()).to.be.equal( + royaltyReceiver.address + ); + + const tnx = await RoyaltyManagerContract.connect( + seller + ).setRoyaltyRecipient(royaltyReceiver2.address); + + await tnx.wait(); + + expect(await splitterContract.recipient()).to.be.equal( + royaltyReceiver2.address + ); + + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + + await splitterContract + .connect(await ethers.getSigner(royaltyReceiver2.address)) + .splitERC20Tokens(ERC20.address); + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + expect(balanceRoyaltyReceiver).to.be.equal(0); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + const balanceRoyaltyReceiver2 = await ERC20.balanceOf( + royaltyReceiver2.address + ); + + expect(balanceRoyaltyReceiver2).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + }); + + it('should receive Royalty(common recipient) in ERC20 to new address set by the admin on registry', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + RoyaltyManagerAsAdmin, + commonRoyaltyReceiver2, + commonRoyaltyReceiver, + royaltyReceiver, + ERC1155AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver.address + ); + + await RoyaltyManagerAsAdmin.setRecipient(commonRoyaltyReceiver2.address); + + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver2.address + ); + + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const balanceCommonRoyaltyReceiver2 = await ERC20.balanceOf( + commonRoyaltyReceiver2.address + ); + + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver2).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + }); + + it('should receive Royalty in ERC20 with new splits set by the admin on registry', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + seller, + buyer, + RoyaltyManagerAsAdmin, + ERC1155AsSeller, + commonRoyaltyReceiver, + royaltyReceiver, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + await RoyaltyManagerAsAdmin.setSplit(6000); + + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + ((1000000 * (erc1155Royalty / 10000)) / 5) * 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + ((1000000 * (erc1155Royalty / 10000)) / 5) * 3 + ); + }); + + it('should split ETH when splitETH method is called', async function () { + const { + RoyaltyManagerContract, + seller, + ERC1155, + deployer, + royaltyReceiver, + } = await royaltyDistribution(); + + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + const royaltyReceiverBalanceWithoutValue = + await ethers.provider.getBalance(royaltyReceiver.address); + const value = ethers.utils.parseUnits('1', 'ether'); + + const royaltyReceiverBalanceWithoutValueNew = + await ethers.provider.getBalance(royaltyReceiver.address); + expect( + royaltyReceiverBalanceWithoutValueNew.sub( + royaltyReceiverBalanceWithoutValue + ) + ).to.be.equal(0); + const royaltyReceiverBalance = await ethers.provider.getBalance( + royaltyReceiver.address + ); + await splitterContract.splitETH({value: value}); + const royaltyReceiverBalanceNew = await ethers.provider.getBalance( + royaltyReceiver.address + ); + + expect(royaltyReceiverBalanceNew.sub(royaltyReceiverBalance)).to.be.equal( + value.div(2) + ); + }); + }); + + describe('Access control', function () { + it('only recipients can split ERC20 tokens', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + deployer, + seller, + buyer, + royaltyReceiver, + ERC1155AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + const balance = await ERC20.balanceOf(splitter); + + expect(balance).to.be.equal(1000000 * (erc1155Royalty / 10000)); + + await expect( + splitterContract.splitERC20Tokens(ERC20.address) + ).to.be.revertedWith( + 'Split: Can only be called by one of the recipients' + ); + }); + + it('creator could change the recipient for his splitter', async function () { + const {ERC1155, seller, royaltyReceiver, RoyaltyManagerContract} = + await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + seller.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + expect(await splitterContract.recipient()).to.be.equal( + royaltyReceiver.address + ); + + const tnx = await RoyaltyManagerContract.connect( + seller + ).setRoyaltyRecipient(seller.address); + + await tnx.wait(); + + expect(await splitterContract.recipient()).to.be.equal(seller.address); + }); + + it('only creator could change the recipient for his splitter', async function () { + const {ERC1155, seller, royaltyReceiver, RoyaltyManagerContract} = + await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await expect( + RoyaltyManagerContract.connect(royaltyReceiver).setRoyaltyRecipient( + seller.address + ) + ).to.revertedWith('Manager: No splitter deployed for the creator'); + }); + + it('manager admin can set common royalty recipient', async function () { + const {seller, commonRoyaltyReceiver, RoyaltyManagerAsAdmin} = + await royaltyDistribution(); + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + commonRoyaltyReceiver.address + ); + await RoyaltyManagerAsAdmin.setRecipient(seller.address); + expect(await RoyaltyManagerAsAdmin.commonRecipient()).to.be.equal( + seller.address + ); + }); + + it('manager admin can set common split', async function () { + const {RoyaltyManagerAsAdmin} = await royaltyDistribution(); + expect(await RoyaltyManagerAsAdmin.commonSplit()).to.be.equal(5000); + await RoyaltyManagerAsAdmin.setSplit(3000); + expect(await RoyaltyManagerAsAdmin.commonSplit()).to.be.equal(3000); + }); + + it('manager admin can set trusted forwarder', async function () { + const {RoyaltyManagerAsAdmin, TrustedForwarder, seller} = + await royaltyDistribution(); + expect(await RoyaltyManagerAsAdmin.getTrustedForwarder()).to.be.equal( + TrustedForwarder.address + ); + await RoyaltyManagerAsAdmin.setTrustedForwarder(seller.address); + expect(await RoyaltyManagerAsAdmin.getTrustedForwarder()).to.be.equal( + seller.address + ); + }); + + it('only manager admin can set trusted forwarder', async function () { + const {RoyaltyManagerContract, seller, managerAdminRole} = + await royaltyDistribution(); + await expect( + RoyaltyManagerContract.connect(seller).setTrustedForwarder( + seller.address + ) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLocaleLowerCase()} is missing role ${managerAdminRole}` + ); + }); + + it('only manager admin can set common royalty recipient', async function () { + const {seller, RoyaltyManagerContract, managerAdminRole} = + await royaltyDistribution(); + await expect( + RoyaltyManagerContract.connect(seller).setRecipient(seller.address) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLocaleLowerCase()} is missing role ${managerAdminRole}` + ); + }); + + it('only contract royalty setter can set common split', async function () { + const {seller, RoyaltyManagerContract, managerAdminRole} = + await royaltyDistribution(); + await expect( + RoyaltyManagerContract.connect(seller).setSplit(3000) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLocaleLowerCase()} is missing role ${managerAdminRole}` + ); + }); + + it('contract royalty setter set Eip 2981 royaltyBps for other contracts', async function () { + const {RoyaltyManagerAsRoyaltySetter, SingleReceiver} = + await royaltyDistribution(); + expect( + await RoyaltyManagerAsRoyaltySetter.contractRoyalty( + SingleReceiver.address + ) + ).to.be.equal(0); + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + SingleReceiver.address, + 500 + ); + }); + + it('only contract royalty setter set Eip 2981 royaltyBps for other contracts', async function () { + const {RoyaltyManagerContract, seller, SingleReceiver} = + await royaltyDistribution(); + + await expect( + RoyaltyManagerContract.connect(seller).setContractRoyalty( + SingleReceiver.address, + 500 + ) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLowerCase()} is missing role ${await RoyaltyManagerContract.CONTRACT_ROYALTY_SETTER_ROLE()}` + ); + }); + it('should be reverted when caller do not have splitter deployer role', async function () { + const { + RoyaltyManagerContract, + seller, + royaltyReceiver, + splitterDeployerRole, + } = await royaltyDistribution(); + await expect( + RoyaltyManagerContract.connect(seller).deploySplitter( + seller.address, + royaltyReceiver.address + ) + ).to.be.revertedWith( + `AccessControl: account ${seller.address.toLocaleLowerCase()} is missing role ${splitterDeployerRole}` + ); + }); + it('should not be reverted when caller have splitter deployer role', async function () { + const { + RoyaltyManagerContract, + seller, + royaltyReceiver, + splitterDeployerRole, + RoyaltyManagerAsAdmin, + } = await royaltyDistribution(); + await RoyaltyManagerAsAdmin.grantRole( + splitterDeployerRole, + seller.address + ); + expect( + await RoyaltyManagerContract.creatorRoyaltiesSplitter(seller.address) + ).to.be.equals('0x0000000000000000000000000000000000000000'); + + await RoyaltyManagerContract.connect(seller).deploySplitter( + seller.address, + royaltyReceiver.address + ); + + expect( + await RoyaltyManagerContract.creatorRoyaltiesSplitter(seller.address) + ).to.not.equals('0x0000000000000000000000000000000000000000'); + }); + }); + + describe('Multi contract splitter setup', function () { + it('should have same splitter address for tokens with minted by same creator', async function () { + const {ERC1155, seller, royaltyReceiver} = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter1 = await ERC1155.getTokenRoyaltiesSplitter(1); + + await ERC1155.connect(seller).mint( + seller.address, + 2, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter2 = await ERC1155.getTokenRoyaltiesSplitter(2); + + expect(splitter1).to.be.equal(splitter2); + }); + + it('should not have same splitter address for tokens with minted by different creator', async function () { + const {ERC1155, seller, buyer, royaltyReceiver} = + await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter1 = await ERC1155.getTokenRoyaltiesSplitter(1); + + await ERC1155.connect(buyer).mint( + buyer.address, + 2, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter2 = await ERC1155.getTokenRoyaltiesSplitter(2); + + expect(splitter1).to.not.be.equal(splitter2); + }); + + it('should return splitter address on for a tokenId on royaltyInfo function call', async function () { + const {ERC1155, seller, royaltyReceiver} = await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter = await ERC1155.getTokenRoyaltiesSplitter(1); + + const royaltyInfo = await ERC1155.royaltyInfo(1, 10000); + + expect(splitter).to.be.equal(royaltyInfo[0]); + }); + it('should return EIP2981 royalty recipient and royalty bps for other contracts from registry(SingleReceiver)', async function () { + const { + commonRoyaltyReceiver, + SingleReceiver, + RoyaltyManagerAsRoyaltySetter, + } = await royaltyDistribution(); + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + SingleReceiver.address, + 500 + ); + const royaltyInfo = await SingleReceiver.royaltyInfo(1, 3000000); + expect(royaltyInfo[0]).to.be.equals(commonRoyaltyReceiver.address); + expect(royaltyInfo[1]).to.be.equals((500 * 3000000) / 10000); + }); + + it('should have same royalty receiver(splitter) for tokens with same creator on ERC1155 and ERC721 using EIP2981(ERC20)', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + ERC1155AsSeller, + RoyaltyManagerContract, + ERC721, + ERC721AsSeller, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + const balance = await ERC20.balanceOf(splitter); + + expect(balance).to.be.equal(1000000 * (erc1155Royalty / 10000)); + + await splitterContract + .connect(royaltyReceiver) + .splitERC20Tokens(ERC20.address); + + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + await ERC721.connect(deployer).mint( + seller.address, + 1, + royaltyReceiver.address + ); + await ERC20.mint(buyer.address, 1000000); + + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC721AsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC721.address, + 1, + buyer.address, + seller.address, + false + ); + const newBalance = await ERC20.balanceOf(splitter); + + const erc721Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC721.address + ); + + expect(newBalance).to.be.equal(1000000 * (erc1155Royalty / 10000)); + + await splitterContract + .connect(royaltyReceiver) + .splitERC20Tokens(ERC20.address); + + const newBalanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + const newBalanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(newBalanceRoyaltyReceiver).to.be.equal( + 1000000 * (erc721Royalty / 10000) + ); + expect(newBalanceCommonRoyaltyReceiver).to.be.equal( + 1000000 * (erc721Royalty / 10000) + ); + }); + + it('should have same royalty receivers(common recipient and creator) for tokens with same creator on ERC1155 and ERC721 using RoyaltyEngine(ERC20) ', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + ERC20AsBuyer, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + RoyaltyRegistry, + ERC1155AsSeller, + ERC721, + ERC721AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + + await RoyaltyRegistry.connect(deployer).setRoyaltyLookupAddress( + ERC1155.address, + ERC1155.address + ); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + const balanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + + const balanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + expect(balanceCommonRoyaltyReceiver).to.be.equal( + (1000000 * (erc1155Royalty / 10000)) / 2 + ); + + await ERC721.connect(deployer).mint( + seller.address, + 1, + royaltyReceiver.address + ); + await ERC20.mint(buyer.address, 1000000); + + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC721AsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace.distributeRoyaltyRoyaltyEngine( + 1000000, + ERC20.address, + ERC721.address, + 1, + buyer.address, + seller.address, + false + ); + const erc721Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC721.address + ); + + const newBalanceRoyaltyReceiver = await ERC20.balanceOf( + royaltyReceiver.address + ); + const newBalanceCommonRoyaltyReceiver = await ERC20.balanceOf( + commonRoyaltyReceiver.address + ); + + expect(newBalanceRoyaltyReceiver).to.be.equal( + 1000000 * (erc721Royalty / 10000) + ); + expect(newBalanceCommonRoyaltyReceiver).to.be.equal( + 1000000 * (erc721Royalty / 10000) + ); + }); + + it('should have same royalty receivers(common recipient and creator) for tokens with same creator on ERC1155 and ERC721 EIP2981(ETH)', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + user, + ERC1155AsSeller, + ERC721, + ERC721AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + const balanceRoyaltyReceiver = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + const value = ethers.utils.parseUnits('1000', 'ether'); + await mockMarketplace + .connect(user) + .distributeRoyaltyEIP2981( + 0, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiver1 = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver1 = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver1.sub(balanceRoyaltyReceiver)).to.be.equal( + balanceCommonRoyaltyReceiver1.sub(balanceCommonRoyaltyReceiver) + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + expect( + balanceRoyaltyReceiver1 + .sub(balanceRoyaltyReceiver) + .add(balanceCommonRoyaltyReceiver1.sub(balanceCommonRoyaltyReceiver)) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)) + ); + + await ERC721.connect(deployer).mint( + seller.address, + 1, + royaltyReceiver.address + ); + await ERC721AsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(user) + .distributeRoyaltyEIP2981( + 0, + ERC20.address, + ERC721.address, + 1, + buyer.address, + seller.address, + false, + { + value: value, + } + ); + const erc721Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC721.address + ); + + const balanceRoyaltyReceiver2 = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver2 = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver2.sub(balanceRoyaltyReceiver1)).to.be.equal( + balanceCommonRoyaltyReceiver2.sub(balanceCommonRoyaltyReceiver1) + ); + + expect( + balanceRoyaltyReceiver2 + .sub(balanceRoyaltyReceiver) + .add(balanceCommonRoyaltyReceiver2.sub(balanceCommonRoyaltyReceiver)) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc721Royalty)) + .div(ethers.BigNumber.from(10000)) + .mul(ethers.BigNumber.from(2)) + ); + }); + + it('should have same royalty receivers(common recipient and creator) for tokens with same creator on ERC1155 and ERC721 using RoyaltyEngine(ETH)', async function () { + const { + ERC1155, + ERC20, + mockMarketplace, + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + user, + ERC1155AsSeller, + ERC721, + ERC721AsSeller, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC1155.connect(seller).setApprovalForAll( + mockMarketplace.address, + true + ); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + const balanceRoyaltyReceiver = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + const value = ethers.utils.parseUnits('1000', 'ether'); + await mockMarketplace + .connect(user) + .distributeRoyaltyRoyaltyEngine( + 0, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true, + { + value: value, + } + ); + + const balanceRoyaltyReceiver1 = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver1 = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver1.sub(balanceRoyaltyReceiver)).to.be.equal( + balanceCommonRoyaltyReceiver1.sub(balanceCommonRoyaltyReceiver) + ); + + const erc1155Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC1155.address + ); + + expect( + balanceRoyaltyReceiver1 + .sub(balanceRoyaltyReceiver) + .add(balanceCommonRoyaltyReceiver1.sub(balanceCommonRoyaltyReceiver)) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc1155Royalty)) + .div(ethers.BigNumber.from(10000)) + ); + + await ERC721.connect(deployer).mint( + seller.address, + 1, + royaltyReceiver.address + ); + await ERC721AsSeller.setApprovalForAll(mockMarketplace.address, true); + + await mockMarketplace + .connect(user) + .distributeRoyaltyEIP2981( + 0, + ERC20.address, + ERC721.address, + 1, + buyer.address, + seller.address, + false, + { + value: value, + } + ); + + const erc721Royalty = await RoyaltyManagerContract.getContractRoyalty( + ERC721.address + ); + + const balanceRoyaltyReceiver2 = await ethers.provider.getBalance( + royaltyReceiver.address + ); + const balanceCommonRoyaltyReceiver2 = await ethers.provider.getBalance( + commonRoyaltyReceiver.address + ); + + expect(balanceRoyaltyReceiver2.sub(balanceRoyaltyReceiver1)).to.be.equal( + balanceCommonRoyaltyReceiver2.sub(balanceCommonRoyaltyReceiver1) + ); + + expect( + balanceRoyaltyReceiver2 + .sub(balanceRoyaltyReceiver) + .add(balanceCommonRoyaltyReceiver2.sub(balanceCommonRoyaltyReceiver)) + ).to.be.equal( + value + .mul(ethers.BigNumber.from(erc721Royalty)) + .div(ethers.BigNumber.from(10000)) + .mul(ethers.BigNumber.from(2)) + ); + }); + + it('should have same splitter address for tokens with minted by same creator on both ERC1155 and ERC721', async function () { + const {ERC1155, seller, royaltyReceiver, ERC721} = + await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + const splitter1 = await ERC1155.getTokenRoyaltiesSplitter(1); + + await ERC721.connect(seller).mint( + seller.address, + 2, + royaltyReceiver.address + ); + + const splitter2 = await ERC721.getTokenRoyaltiesSplitter(2); + + expect(splitter1).to.be.equal(splitter2); + }); + + it('should return creator royalty splitter from Royalty manager', async function () { + const { + RoyaltyManagerContract, + seller, + ERC1155, + deployer, + royaltyReceiver, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + expect( + await RoyaltyManagerContract.getCreatorRoyaltySplitter(deployer.address) + ).to.be.equal(await ERC1155.getTokenRoyaltiesSplitter(1)); + }); + it('should emit Token Royalty Splitter set event when a token is minted for first time', async function () { + const {seller, ERC1155, deployer, royaltyReceiver} = + await royaltyDistribution(); + + const mintTx = await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const mintResult = await mintTx.wait(); + const splitterSetEvent = mintResult.events[5]; + expect(splitterSetEvent.event).to.equal('TokenRoyaltySplitterSet'); + }); + it('should not emit Token Royalty Splitter set event when a token is minted for second time', async function () { + const {seller, ERC1155, deployer, royaltyReceiver} = + await royaltyDistribution(); + const mintTx = await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const mintResult = await mintTx.wait(); + const splitterSetEvent = mintResult.events[5]; + expect(splitterSetEvent.event).to.equal('TokenRoyaltySplitterSet'); + const mintTx2 = await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const mintResult2 = await mintTx2.wait(); + for (let i = 0; i < mintResult2.events.length; i++) { + expect(mintResult.events[i].event).to.not.equal( + 'TokenRoyaltySplitterSet' + ); + } + }); + it('should emit recipient set event when a token minted for the first time', async function () { + const {seller, ERC1155, deployer, royaltyReceiver} = + await royaltyDistribution(); + const mintTx = await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const mintResult = await mintTx.wait(); + const log = mintResult.logs[1]; + expect(log.topics[0]).to.be.equal( + ethers.utils.id('RecipientSet(address)') + ); + }); + it('should not emit recipient set event when token is minted for second time', async function () { + const {seller, ERC1155, deployer, royaltyReceiver} = + await royaltyDistribution(); + const mintTx = await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const mintResult = await mintTx.wait(); + const log = mintResult.logs[1]; + expect(log.topics[0]).to.be.equal( + ethers.utils.id('RecipientSet(address)') + ); + const mintTx2 = await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const mintResult2 = await mintTx2.wait(); + for (let i = 0; i < mintResult2.events.length; i++) { + expect(mintResult.logs[i].topics[0]).to.not.equal( + ethers.utils.id('RecipientSet(address)') + ); + } + }); + }); + + describe('Input validation', function () { + it('should revert setting royalty recipient when no splitter is deployed', async function () { + const {RoyaltyManagerContract, seller} = await royaltyDistribution(); + await expect( + RoyaltyManagerContract.connect(seller).setRoyaltyRecipient( + seller.address + ) + ).to.be.revertedWith('Manager: No splitter deployed for the creator'); + }); + it('should revert setting royalty recipient when recipient is set again', async function () { + const {RoyaltyManagerContract, seller, ERC1155, royaltyReceiver} = + await royaltyDistribution(); + await ERC1155.connect(seller).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await expect( + RoyaltyManagerContract.connect(seller).setRoyaltyRecipient( + royaltyReceiver.address + ) + ).to.be.revertedWith('Manager: Recipient already set'); + }); + it('should revert if when contract royalties is greater than total basis points', async function () { + const { + RoyaltyManagerContract, + SingleReceiver, + RoyaltyManagerAsRoyaltySetter, + } = await royaltyDistribution(); + + await expect( + RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + SingleReceiver.address, + 10001 + ) + ).to.be.revertedWith( + "Manager: Royalty can't be greater than Total base points" + ); + await expect( + RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + SingleReceiver.address, + 500 + ) + ) + .to.emit(RoyaltyManagerContract, 'RoyaltySet') + .withArgs(500, SingleReceiver.address); + }); + it('should revert when setRecipients in splitter called by not owner', async function () { + const { + RoyaltyManagerContract, + deployer, + user, + ERC20, + ERC1155, + seller, + royaltyReceiver, + buyer, + ERC20AsBuyer, + mockMarketplace, + ERC1155AsSeller, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + await expect( + splitterContract.connect(user).setRecipients([]) + ).to.be.revertedWith('Ownable: caller is not the owner'); + }); + + it('should revert when split called by non-recipients', async function () { + const { + RoyaltyManagerContract, + seller, + buyer, + ERC1155, + ERC20AsBuyer, + mockMarketplace, + ERC1155AsSeller, + deployer, + user, + ERC20, + royaltyReceiver, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + await expect( + splitterContract.connect(user).splitERC20Tokens(ERC20.address) + ).to.be.revertedWith( + 'Split: Can only be called by one of the recipients' + ); + }); + it('should revert when zero balance of split tokens', async function () { + const { + RoyaltyManagerContract, + seller, + buyer, + ERC1155, + ERC20AsBuyer, + mockMarketplace, + ERC1155AsSeller, + deployer, + ERC20, + royaltyReceiver, + RoyaltyManagerAsRoyaltySetter, + } = await royaltyDistribution(); + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + ERC1155.address, + 0 + ); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + await ERC20.mint(buyer.address, 1000000); + await ERC20AsBuyer.approve(mockMarketplace.address, 1000000); + await ERC1155AsSeller.setApprovalForAll(mockMarketplace.address, true); + expect(await ERC1155.balanceOf(seller.address, 1)).to.be.equals(1); + await mockMarketplace.distributeRoyaltyEIP2981( + 1000000, + ERC20.address, + ERC1155.address, + 1, + buyer.address, + seller.address, + true + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + await expect( + splitterContract + .connect(royaltyReceiver) + .splitERC20Tokens(ERC20.address) + ).to.be.revertedWith('Split: ERC20 split failed'); + }); + + it('should revert when recipient is set for a creator with no splitter', async function () { + const {RoyaltyManagerContract, deployer} = await royaltyDistribution(); + + await expect( + RoyaltyManagerContract.connect(deployer).setRoyaltyRecipient( + zeroAddress + ) + ).to.be.revertedWith('Manager: No splitter deployed for the creator'); + }); + + it('should revert on for overflow for try mul in splitter contract', async function () { + const { + ERC1155, + deployer, + seller, + royaltyReceiver, + RoyaltyManagerContract, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const TestERC20Factory = await ethers.getContractFactory( + 'OverflowTestERC20' + ); + const OverflowERC20 = await TestERC20Factory.deploy(); + + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + + await OverflowERC20.mintMax(splitter); + await expect( + splitterContract + .connect(royaltyReceiver) + .splitERC20Tokens(OverflowERC20.address) + ).to.be.revertedWith('RoyaltySplitter: Multiplication Overflow'); + }); + }); + + describe('Interfaces', function () { + it('should support interface for Royalty Splitter', async function () { + const { + RoyaltyManagerContract, + deployer, + ERC1155, + seller, + royaltyReceiver, + } = await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const splitter = await RoyaltyManagerContract.creatorRoyaltiesSplitter( + deployer.address + ); + + const splitterContract = await ethers.getContractAt( + splitterAbi, + splitter + ); + expect(await splitterContract.supportsInterface(0x16cf0c05)).to.be.equal( + true + ); + }); + it('should support interface for royalty distributer', async function () { + const {SingleReceiver} = await royaltyDistribution(); + + expect(await SingleReceiver.supportsInterface(0x2a55205a)).to.be.equal( + true + ); + }); + + it('should support interface for multiRoyalty distributer', async function () { + const {ERC1155} = await royaltyDistribution(); + expect(await ERC1155.supportsInterface(0x2a55205a)).to.be.equal(true); + }); + }); + + describe('Single receiver for contracts which have single royalty recipient (common recipient)', function () { + it('Should return contract royalty from manager for single receiver', async function () { + const {RoyaltyManagerAsRoyaltySetter, SingleReceiver} = + await royaltyDistribution(); + expect( + await RoyaltyManagerAsRoyaltySetter.contractRoyalty( + SingleReceiver.address + ) + ).to.be.equal(0); + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + SingleReceiver.address, + 500 + ); + expect( + await RoyaltyManagerAsRoyaltySetter.contractRoyalty( + SingleReceiver.address + ) + ).to.be.equal(500); + }); + }); + + describe('Royalty recipients', function () { + it('should return splitter address in royalty info', async function () { + const {ERC1155, royaltyReceiver, deployer, seller} = + await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + + expect(await ERC1155.royaltyInfo(1, 0)).to.deep.equal([ + await ERC1155.getTokenRoyaltiesSplitter(1), + 0, + ]); + }); + it('should return common royalty recipient address in when no splitter is set for a token', async function () { + const {ERC1155, commonRoyaltyReceiver} = await royaltyDistribution(); + + expect(await ERC1155.royaltyInfo(1, 0)).to.deep.equal([ + commonRoyaltyReceiver.address, + 0, + ]); + }); + it('should return zero address and zero bps when set for token which have no splitter deployed', async function () { + const {ERC1155, RoyaltyManagerAsRoyaltySetter} = + await royaltyDistribution(); + + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty( + ERC1155.address, + 0 + ); + expect(await ERC1155.royaltyInfo(2, 1000)).to.deep.equal(['0', 0x00]); + }); + it('should return all the royalty recipient form the contract', async function () { + const {ERC1155, commonRoyaltyReceiver, seller, user, deployer} = + await royaltyDistribution(); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + user.address, + '0x' + ); + expect(await ERC1155.getAllSplits()).to.deep.equal([ + commonRoyaltyReceiver.address, + await ERC1155.getTokenRoyaltiesSplitter(1), + ]); + }); + it('should return all the royalty recipient of a token', async function () { + const { + ERC1155, + royaltyReceiver, + deployer, + seller, + commonRoyaltyReceiver, + } = await royaltyDistribution(); + + expect((await ERC1155.getRecipients(1))[0].recipient).to.be.equal( + commonRoyaltyReceiver.address + ); + await ERC1155.connect(deployer).mint( + seller.address, + 1, + 1, + royaltyReceiver.address, + '0x' + ); + const recipients = await ERC1155.getRecipients(1); + expect(recipients[0].recipient).to.deep.equal(royaltyReceiver.address); + expect(recipients[1].recipient).to.deep.equal( + commonRoyaltyReceiver.address + ); + }); + }); +}); diff --git a/packages/dependency-royalty-management/test/Splitter.abi.ts b/packages/dependency-royalty-management/test/Splitter.abi.ts new file mode 100644 index 0000000000..3d0d752164 --- /dev/null +++ b/packages/dependency-royalty-management/test/Splitter.abi.ts @@ -0,0 +1,280 @@ +export const splitterAbi = [ + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'erc20Contract', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ERC20Transferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ETHTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'recipientAddress', + type: 'address', + }, + ], + name: 'RecipientSet', + type: 'event', + }, + { + inputs: [], + name: 'getRecipients', + outputs: [ + { + components: [ + { + internalType: 'address payable', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint16', + name: 'bps', + type: 'uint16', + }, + ], + internalType: 'struct Recipient[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address payable', + name: '_recipient', + type: 'address', + }, + { + internalType: 'address', + name: '_royaltyManager', + type: 'address', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'forwarder', + type: 'address', + }, + ], + name: 'isTrustedForwarder', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'recipient', + outputs: [ + { + internalType: 'address payable', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'royaltyManager', + outputs: [ + { + internalType: 'contract IRoyaltyManager', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address payable', + name: 'recipient', + type: 'address', + }, + { + internalType: 'uint16', + name: 'bps', + type: 'uint16', + }, + ], + internalType: 'struct Recipient[]', + name: 'recipients', + type: 'tuple[]', + }, + ], + name: 'setRecipients', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'erc20Contract', + type: 'address', + }, + ], + name: 'splitERC20Tokens', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'splitETH', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes4', + name: 'interfaceId', + type: 'bytes4', + }, + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + stateMutability: 'payable', + type: 'receive', + }, +]; diff --git a/packages/dependency-royalty-management/test/fixture.ts b/packages/dependency-royalty-management/test/fixture.ts new file mode 100644 index 0000000000..79d4042ba1 --- /dev/null +++ b/packages/dependency-royalty-management/test/fixture.ts @@ -0,0 +1,163 @@ +import {ethers, upgrades} from 'hardhat'; + +export async function royaltyDistribution() { + const [ + deployer, + seller, + buyer, + commonRoyaltyReceiver, + royaltyReceiver, + user, + commonRoyaltyReceiver2, + royaltyReceiver2, + managerAdmin, + contractRoyaltySetter, + ] = await ethers.getSigners(); + + const TrustedForwarderFactory = await ethers.getContractFactory( + 'MockTrustedForwarder' + ); + const TrustedForwarder = await TrustedForwarderFactory.deploy(); + + const TestERC20Factory = await ethers.getContractFactory('TestERC20'); + const ERC20 = await TestERC20Factory.deploy('TestERC20', 'T'); + + const RoyaltySplitterFactory = await ethers.getContractFactory( + 'RoyaltySplitter' + ); + const RoyaltySplitter = await RoyaltySplitterFactory.deploy(); + + const RoyaltyManagerFactory = await ethers.getContractFactory( + 'RoyaltyManager' + ); + const RoyaltyManagerContract = await upgrades.deployProxy( + RoyaltyManagerFactory, + [ + commonRoyaltyReceiver.address, + 5000, + RoyaltySplitter.address, + managerAdmin.address, + contractRoyaltySetter.address, + TrustedForwarder.address, + ], + { + initializer: 'initialize', + } + ); + await RoyaltyManagerContract.deployed(); + + const TestERC1155Factory = await ethers.getContractFactory('TestERC1155'); + const ERC1155 = await upgrades.deployProxy( + TestERC1155Factory, + [RoyaltyManagerContract.address, TrustedForwarder.address], + { + initializer: 'initialize', + } + ); + + await ERC1155.deployed(); + + const TestERC721Factory = await ethers.getContractFactory('TestERC721'); + const ERC721 = await upgrades.deployProxy( + TestERC721Factory, + [RoyaltyManagerContract.address, TrustedForwarder.address], + { + initializer: 'initialize', + } + ); + + const SingleReceiverFactory = await ethers.getContractFactory( + 'SingleReceiver' + ); + const SingleReceiver = await upgrades.deployProxy( + SingleReceiverFactory, + [RoyaltyManagerContract.address, TrustedForwarder.address], + { + initializer: 'initialize', + } + ); + + await ERC721.deployed(); + + const FallbackRegistryFactory = await ethers.getContractFactory( + 'FallbackRegistry' + ); + const FallbackRegistry = await FallbackRegistryFactory.deploy( + deployer.address + ); + + const RoyaltyRegistryFactory = await ethers.getContractFactory( + 'RoyaltyRegistry' + ); + const RoyaltyRegistry = await RoyaltyRegistryFactory.deploy( + '0x0000000000000000000000000000000000000000' + ); + + const RoyaltyEngineFactory = await ethers.getContractFactory( + 'RoyaltyEngineV1' + ); + const RoyaltyEngineV1 = await RoyaltyEngineFactory.deploy( + FallbackRegistry.address + ); + + await RoyaltyEngineV1.initialize(deployer.address, RoyaltyRegistry.address); + + const MockMarketPlaceFactory = await ethers.getContractFactory( + 'MockMarketplace' + ); + const mockMarketplace = await MockMarketPlaceFactory.deploy( + RoyaltyEngineV1.address + ); + + const managerAdminRole = await RoyaltyManagerContract.DEFAULT_ADMIN_ROLE(); + const contractRoyaltySetterRole = + await RoyaltyManagerContract.CONTRACT_ROYALTY_SETTER_ROLE(); + const splitterDeployerRole = + await RoyaltyManagerContract.SPLITTER_DEPLOYER_ROLE(); + const RoyaltyManagerAsAdmin = RoyaltyManagerContract.connect(managerAdmin); + const RoyaltyManagerAsRoyaltySetter = RoyaltyManagerContract.connect( + contractRoyaltySetter + ); + + const NFTFactory = await ethers.getContractFactory('NFTWithoutTransferCheck'); + const NFT = await NFTFactory.deploy(); + + const ERC1155AsSeller = ERC1155.connect(seller); + const ERC20AsBuyer = ERC20.connect(buyer); + const ERC721AsSeller = ERC721.connect(seller); + + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty(ERC1155.address, 300); + await RoyaltyManagerAsRoyaltySetter.setContractRoyalty(ERC721.address, 300); + await RoyaltyManagerAsAdmin.grantRole(splitterDeployerRole, ERC1155.address); + await RoyaltyManagerAsAdmin.grantRole(splitterDeployerRole, ERC721.address); + + return { + ERC1155, + ERC20, + RoyaltyManagerContract, + mockMarketplace, + ERC1155AsSeller, + ERC20AsBuyer, + deployer, + seller, + buyer, + user, + commonRoyaltyReceiver, + royaltyReceiver, + RoyaltyRegistry, + commonRoyaltyReceiver2, + royaltyReceiver2, + ERC721, + ERC721AsSeller, + managerAdmin, + managerAdminRole, + contractRoyaltySetter, + RoyaltyManagerAsAdmin, + contractRoyaltySetterRole, + RoyaltyManagerAsRoyaltySetter, + SingleReceiver, + NFT, + TrustedForwarder, + splitterDeployerRole, + }; +} diff --git a/packages/dependency-royalty-management/tsconfig.json b/packages/dependency-royalty-management/tsconfig.json new file mode 100644 index 0000000000..790a8309cf --- /dev/null +++ b/packages/dependency-royalty-management/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + }, + "include": [ + "hardhat.config.ts", + "./typechain-types", + "./test" + ] +} diff --git a/packages/deploy/.env.example b/packages/deploy/.env.example new file mode 100644 index 0000000000..79f9459ea8 --- /dev/null +++ b/packages/deploy/.env.example @@ -0,0 +1,42 @@ +# seed-phrase for the wallet to use on default network +# this is required for local testing otherwise hardhat will throw "Invalid mnemonic" +MNEMONIC=xxxxxxxxxxxxxxxxxxxxxx + +# seed-phrase for the wallet to use on mainnet +MNEMONIC_MAINNET=xxxxxxxxxxxxxxxxxxxxxx + +# seed-phrase for the wallet to use on goerli +MNEMONIC_GOERLI=xxxxxxxxxxxxxxxxxxxxxx + +# seed-phrase for the wallet to use on mumbai +MNEMONIC_MUMBAI=xxxxxxxxxxxxxxxxxxxxxx + +# mainnet provider URI +ETH_NODE_URI_MAINNET=xxxxxxxxxxxxxxxxxxxxxx + +# goerli provider URI +ETH_NODE_URI_GOERLI=xxxxxxxxxxxxxxxxxxxxxx + +# goerli provider URI +ETH_NODE_URI_MUMBAI=xxxxxxxxxxxxxxxxxxxxxx + +# provider URI for testnets +ETH_NODE_URI=xxxxxxxxxxxxxxxxxxxxxx + +# polygon provider URI +ETH_NODE_URI_POLYGON=xxxxxxxxxxxxxxxxxxxxxx + +# API key for etherscan verification +ETHERSCAN_API_KEY_MAINNET=xxxxxxxxxxxxxxxxxxxxxx +ETHERSCAN_API_KEY_GOERLI=xxxxxxxxxxxxxxxxxxxxxx +ETHERSCAN_API_KEY_POLYGON=xxxxxxxxxxxxxxxxxxxxxx +ETHERSCAN_API_KEY_MUMBAI=xxxxxxxxxxxxxxxxxxxxxx + +# Options to increase Node process memory (useful when running yarn coverage for example on some machine) +NODE_OPTIONS=--max-old-space-size=8192 + +INFURA_HTTP_BLOCK_QUERY_LIMIT=1000 + +# THE GRAPH URL +CLAIMS_GRAPH_URL_MUMBAI=xxxxxxxxxxxxxxxxxxxxxx +CLAIMS_GRAPH_URL_POLYGON=xxxxxxxxxxxxxxxxxxxxxx diff --git a/packages/deploy/contracts/mocks/AuthValidator.sol b/packages/deploy/contracts/mocks/AuthValidator.sol new file mode 100644 index 0000000000..09122fb0bf --- /dev/null +++ b/packages/deploy/contracts/mocks/AuthValidator.sol @@ -0,0 +1,27 @@ +//SPDX-License-Identifier: MIT + +pragma solidity 0.8.18; + +/// @title AuthValidator +/// @author The Sandbox +/// @notice This contract is used to validate the signature of the backend +contract AuthValidatorMock { + mapping(bytes32 => bool) public valid; + /// @dev Constructor + /// @param admin Address of the admin that will be able to grant roles + /// @param initialSigningWallet Address of the initial signing wallet that will be signing on behalf of the backend + constructor(address admin, address initialSigningWallet) { + } + + /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned + /// @dev Multipurpose function that can be used to verify signatures with different digests + /// @param digest Digest hash + /// @return bool + function verify(bytes memory /*signature*/, bytes32 digest) public view returns (bool) { + return valid[digest]; + } + + function setValid(bytes32 digest, bool val) external { + valid[digest] = val; + } +} diff --git a/packages/deploy/deploy/200_royalties/200_deploy_royalty_splitter.ts b/packages/deploy/deploy/200_royalties/200_deploy_royalty_splitter.ts new file mode 100644 index 0000000000..0cf3fb722a --- /dev/null +++ b/packages/deploy/deploy/200_royalties/200_deploy_royalty_splitter.ts @@ -0,0 +1,21 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +const func: DeployFunction = async function ( + hre: HardhatRuntimeEnvironment +): Promise { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + + await deploy('RoyaltySplitter', { + from: deployer, + log: true, + contract: + '@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter', + skipIfAlreadyDeployed: true, + }); +}; +export default func; +func.tags = ['RoyaltySplitter', 'RoyaltySplitter_deploy', 'L2']; diff --git a/packages/deploy/deploy/200_royalties/201_deploy_royalty_manager.ts b/packages/deploy/deploy/200_royalties/201_deploy_royalty_manager.ts new file mode 100644 index 0000000000..155e3a0f9c --- /dev/null +++ b/packages/deploy/deploy/200_royalties/201_deploy_royalty_manager.ts @@ -0,0 +1,49 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +export const ROYALTY_SPLIT = 5000; + +const func: DeployFunction = async function ( + hre: HardhatRuntimeEnvironment +): Promise { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const { + deployer, + upgradeAdmin, + commonRoyaltyReceiver, + royaltyManagerAdmin, + contractRoyaltySetter, + } = await getNamedAccounts(); + + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + const RoyaltySplitter = await deployments.get('RoyaltySplitter'); + + await deploy('RoyaltyManager', { + from: deployer, + log: true, + contract: + '@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager', + proxy: { + owner: upgradeAdmin, + proxyContract: 'OpenZeppelinTransparentProxy', + execute: { + methodName: 'initialize', + args: [ + commonRoyaltyReceiver, + ROYALTY_SPLIT, + RoyaltySplitter.address, + royaltyManagerAdmin, + contractRoyaltySetter, + TRUSTED_FORWARDER.address, + ], + }, + upgradeIndex: 0, + }, + skipIfAlreadyDeployed: true, + }); +}; +export default func; +func.tags = ['RoyaltyManager', 'RoyaltyManager_deploy', 'L2']; +func.dependencies = ['RoyaltySplitter_deploy', 'TRUSTED_FORWARDER_V2']; diff --git a/packages/deploy/deploy/300_catalyst/300_catalyst_mint.ts b/packages/deploy/deploy/300_catalyst/300_catalyst_mint.ts new file mode 100644 index 0000000000..53509e2d79 --- /dev/null +++ b/packages/deploy/deploy/300_catalyst/300_catalyst_mint.ts @@ -0,0 +1,50 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {execute, catchUnknownSigner, log} = deployments; + const {catalystMinter} = await getNamedAccounts(); + + const mumbaiGivewayContractAddress = + '0xfCE84d07909489508C5B293a850AF15Fb7147bc6'; + const polygonGiveawayContractAddress = + '0x214d52880b1e4E17d020908cd8EAa988FfDD4020'; + + const giveawayContractAddress = + hre.network.name === 'mumbai' + ? mumbaiGivewayContractAddress + : polygonGiveawayContractAddress; + + // TODO Specify amounts + const amounts = { + Common: 100, + Uncommon: 200, + Rare: 300, + Epic: 400, + Legendary: 500, + Mythic: 600, + }; + await catchUnknownSigner( + execute( + 'Catalyst', + {from: catalystMinter, log: true}, + 'mintBatch', + giveawayContractAddress, + [1, 2, 3, 4, 5, 6], + [ + amounts.Common, + amounts.Uncommon, + amounts.Rare, + amounts.Epic, + amounts.Legendary, + amounts.Mythic, + ] + ) + ); + log(`Minted 6 NFTs to ${giveawayContractAddress}`); +}; + +export default func; +func.tags = ['Catalyst_mint', 'L2']; +func.dependencies = ['Catalyst_deploy']; diff --git a/packages/deploy/deploy/300_catalyst/300_deploy_operator_filter_subscription.ts b/packages/deploy/deploy/300_catalyst/300_deploy_operator_filter_subscription.ts new file mode 100644 index 0000000000..bc4d1edff3 --- /dev/null +++ b/packages/deploy/deploy/300_catalyst/300_deploy_operator_filter_subscription.ts @@ -0,0 +1,26 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + + // TODO: review subscriptions for Catalyst and Asset + + // Operator filter subscription + await deploy('OperatorFilterSubscription', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFilterSubscription.sol:OperatorFilterSubscription', + log: true, + skipIfAlreadyDeployed: true, + }); +}; +export default func; +func.tags = [ + 'OperatorFilterSubscription', + 'OperatorFilterSubscription_deploy', + 'L2', +]; diff --git a/packages/deploy/deploy/300_catalyst/301_deploy_catalyst.ts b/packages/deploy/deploy/300_catalyst/301_deploy_catalyst.ts new file mode 100644 index 0000000000..a8fa7d26a2 --- /dev/null +++ b/packages/deploy/deploy/300_catalyst/301_deploy_catalyst.ts @@ -0,0 +1,62 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +export const CATALYST_BASE_URI = 'ipfs://'; + +// TODO: update for polygon-mainnet deployment +export const CATALYST_IPFS_CID_PER_TIER = [ + 'bafybeiecnz7snx763tcxwbsitbucltcxp7ma5siqbgda35bl3tsfeeti4m', // TSB Exclusive + 'bafkreib5tky3dgsc7zy637dfunb4zwwnpzo3w3i5tepbfee42eq3srwnwq', // Common + 'bafkreiegevvim5q3ati4htsncxwsejfc3lbkzb7wn2a2fzthc6tsof7v7m', // Uncommon + 'bafkreifhtkou5a32xrtktdvfqrvgh4mp2ohvlyqdsih5xk4kgcfywtxefi', // Rare + 'bafkreigqpb7qo3iqka4243oah3nka6agx3nmvwzauxze2jznotx3zwozqe', // Epic + 'bafkreih3itsiwkn2urzfvg26mby3ssgfshvdr6zfabr6rxxrlzhedqil4e', // Legendary + 'bafkreibmngauozzidz2eevyyb3umf2ew7zexing3ghup6l7io2ao522mvy', // Mythic +]; + +const func: DeployFunction = async function ( + hre: HardhatRuntimeEnvironment +): Promise { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer, upgradeAdmin, catalystMinter, catalystAdmin} = + await getNamedAccounts(); + + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + const OperatorFilterSubscription = await deployments.get( + 'OperatorFilterSubscription' + ); + const RoyaltyManager = await deployments.get('RoyaltyManager'); + + await deploy('Catalyst', { + from: deployer, + log: true, + contract: '@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst', + proxy: { + owner: upgradeAdmin, + proxyContract: 'OpenZeppelinTransparentProxy', + execute: { + methodName: 'initialize', + args: [ + CATALYST_BASE_URI, + TRUSTED_FORWARDER.address, + OperatorFilterSubscription.address, + catalystAdmin, // DEFAULT_ADMIN_ROLE + catalystMinter, // MINTER_ROLE + CATALYST_IPFS_CID_PER_TIER, + RoyaltyManager.address, + ], + }, + upgradeIndex: 0, + }, + skipIfAlreadyDeployed: true, + }); +}; +export default func; +func.tags = ['Catalyst', 'Catalyst_deploy', 'L2']; +func.dependencies = [ + 'OperatorFilterSubscription_deploy', + 'RoyaltyManager_deploy', + 'TRUSTED_FORWARDER_V2', +]; diff --git a/packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts b/packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts new file mode 100644 index 0000000000..2ab6aab47f --- /dev/null +++ b/packages/deploy/deploy/300_catalyst/302_catalyst_setup.ts @@ -0,0 +1,82 @@ +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +// TODO this should not be hardcoded here +export const royaltyAmount = 500; + +const func: DeployFunction = async function ( + hre: HardhatRuntimeEnvironment +): Promise { + const {deployments, getNamedAccounts} = hre; + const {execute, read, catchUnknownSigner, log} = deployments; + const {catalystAdmin, contractRoyaltySetter} = await getNamedAccounts(); + + // TODO Remove below before mainnet deployment + const minterRole = await read('Catalyst', 'MINTER_ROLE'); + if ( + !(await read( + 'Catalyst', + 'hasRole', + minterRole, + '0xf41671100948bcb80CB9eFbD3fba16c2898d9ef7' // Diego's mumbai wallet + )) + ) { + await catchUnknownSigner( + execute( + 'Catalyst', + {from: catalystAdmin, log: true}, + 'grantRole', + minterRole, + '0xf41671100948bcb80CB9eFbD3fba16c2898d9ef7' + ) + ); + log(`MINTER_ROLE granted to 0xf41671100948bcb80CB9eFbD3fba16c2898d9ef7`); + } + if ( + !(await read( + 'Catalyst', + 'hasRole', + minterRole, + '0x803E1522e136121c058dc9541E7B3164957c200e' // Seba's mumbai wallet + )) + ) { + await catchUnknownSigner( + execute( + 'Catalyst', + {from: catalystAdmin, log: true}, + 'grantRole', + minterRole, + '0x803E1522e136121c058dc9541E7B3164957c200e' + ) + ); + log(`MINTER_ROLE granted to 0x803E1522e136121c058dc9541E7B3164957c200e`); + } + // TODO END + + // set catalyst on Royalty Manager + const catalyst = await deployments.get('Catalyst'); + + if ( + (await read( + 'RoyaltyManager', + {from: contractRoyaltySetter}, + 'contractRoyalty', + catalyst.address + )) === 0 + ) { + await catchUnknownSigner( + execute( + 'RoyaltyManager', + {from: contractRoyaltySetter, log: true}, + 'setContractRoyalty', + catalyst.address, + royaltyAmount + ) + ); + log(`Catalyst set on RoyaltyManager with ${royaltyAmount} BPS royalty`); + } +}; + +export default func; +func.tags = ['Catalyst', 'Catalyst_setup', 'L2']; +func.dependencies = ['Catalyst_deploy', 'RoyaltyManager_deploy']; diff --git a/packages/deploy/deploy/400_asset/400_asset_operator_filter_setup.ts b/packages/deploy/deploy/400_asset/400_asset_operator_filter_setup.ts new file mode 100644 index 0000000000..8441e7963f --- /dev/null +++ b/packages/deploy/deploy/400_asset/400_asset_operator_filter_setup.ts @@ -0,0 +1,37 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; +const DEFAULT_SUBSCRIPTION = '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'; +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {filterOperatorSubscription} = await getNamedAccounts(); + const {execute, read} = deployments; + + const operatorFilterRegistry = await deployments.getOrNull( + 'OPERATOR_FILTER_REGISTRY' + ); + + if (operatorFilterRegistry) { + const registered = await read( + 'OPERATOR_FILTER_REGISTRY', + 'isRegistered', + filterOperatorSubscription + ); + + // register filterOperatorSubscription + if (!registered) { + await execute( + 'OPERATOR_FILTER_REGISTRY', + {from: filterOperatorSubscription}, + 'registerAndCopyEntries', + filterOperatorSubscription, + DEFAULT_SUBSCRIPTION + ); + console.log( + "common subscription registered on operator filter registry and OpenSea's blacklist copied" + ); + } + } +}; +export default func; + +func.tags = ['OperatorFilter', 'OperatorFilter_setup', 'L2']; diff --git a/packages/deploy/deploy/400_asset/401_deploy_asset_auth_validator.ts b/packages/deploy/deploy/400_asset/401_deploy_asset_auth_validator.ts new file mode 100644 index 0000000000..332a7586be --- /dev/null +++ b/packages/deploy/deploy/400_asset/401_deploy_asset_auth_validator.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer, assetAdmin} = await getNamedAccounts(); + await deploy('AuthSuperValidator', { + from: deployer, + contract: 'AuthSuperValidator', + args: [assetAdmin], + log: true, + }); +}; +export default func; +func.tags = ['AuthSuperValidator', 'AuthSuperValidator_deploy', 'L2']; diff --git a/packages/deploy/deploy/400_asset/402_deploy_asset.ts b/packages/deploy/deploy/400_asset/402_deploy_asset.ts new file mode 100644 index 0000000000..b970483a12 --- /dev/null +++ b/packages/deploy/deploy/400_asset/402_deploy_asset.ts @@ -0,0 +1,41 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + const {deployer, assetAdmin, upgradeAdmin, filterOperatorSubscription} = + await getNamedAccounts(); + + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + const RoyaltyManager = await deployments.get('RoyaltyManager'); + + await deploy('Asset', { + from: deployer, + contract: '@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset', + proxy: { + owner: upgradeAdmin, + proxyContract: 'OpenZeppelinTransparentProxy', + execute: { + methodName: 'initialize', + args: [ + TRUSTED_FORWARDER.address, + assetAdmin, + 'ipfs://', + filterOperatorSubscription, + RoyaltyManager.address, + ], + }, + upgradeIndex: 0, + }, + log: true, + }); +}; +export default func; + +func.tags = ['Asset', 'Asset_deploy', 'L2']; +func.dependencies = [ + 'TRUSTED_FORWARDER_V2', + 'RoyaltyManager_deploy', + 'OperatorFilter_setup', +]; diff --git a/packages/deploy/deploy/400_asset/403_deploy_asset_create.ts b/packages/deploy/deploy/400_asset/403_deploy_asset_create.ts new file mode 100644 index 0000000000..07853e4179 --- /dev/null +++ b/packages/deploy/deploy/400_asset/403_deploy_asset_create.ts @@ -0,0 +1,51 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + const {deployer, assetAdmin, upgradeAdmin} = await getNamedAccounts(); + + const AssetContract = await deployments.get('Asset'); + const AuthValidatorContract = await deployments.get('AuthSuperValidator'); + const CatalystContract = await deployments.get('Catalyst'); + + const name = 'Sandbox Asset Create'; + const version = '1.0'; + + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + + await deploy('AssetCreate', { + from: deployer, + contract: + '@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate', + proxy: { + owner: upgradeAdmin, + proxyContract: 'OpenZeppelinTransparentProxy', + execute: { + methodName: 'initialize', + args: [ + name, + version, + AssetContract.address, + CatalystContract.address, + AuthValidatorContract.address, + TRUSTED_FORWARDER.address, + assetAdmin, // DEFAULT_ADMIN_ROLE + ], + }, + upgradeIndex: 0, + }, + log: true, + }); +}; +export default func; + +func.tags = ['Asset', 'AssetCreate', 'AssetCreate_deploy', 'L2']; +func.dependencies = [ + 'Asset_deploy', + 'Catalyst_deploy', + 'Catalyst_setup', + 'AuthSuperValidator_deploy', + 'TRUSTED_FORWARDER_V2', +]; diff --git a/packages/deploy/deploy/400_asset/404_deploy_asset_reveal.ts b/packages/deploy/deploy/400_asset/404_deploy_asset_reveal.ts new file mode 100644 index 0000000000..6b434e1b51 --- /dev/null +++ b/packages/deploy/deploy/400_asset/404_deploy_asset_reveal.ts @@ -0,0 +1,47 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + const {deployer, upgradeAdmin, assetAdmin} = await getNamedAccounts(); + + const AssetContract = await deployments.get('Asset'); + const AuthValidatorContract = await deployments.get('AuthSuperValidator'); + + const name = 'Sandbox Asset Reveal'; + const version = '1.0'; + + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + + await deploy('AssetReveal', { + from: deployer, + contract: + '@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal', + proxy: { + owner: upgradeAdmin, + proxyContract: 'OpenZeppelinTransparentProxy', + execute: { + methodName: 'initialize', + args: [ + name, + version, + AssetContract.address, + AuthValidatorContract.address, + TRUSTED_FORWARDER.address, + assetAdmin, + ], + }, + upgradeIndex: 0, + }, + log: true, + }); +}; +export default func; + +func.tags = ['Asset', 'AssetReveal', 'AssetReveal_deploy', 'L2']; +func.dependencies = [ + 'Asset_deploy', + 'AuthSuperValidator_deploy', + 'TRUSTED_FORWARDER_V2', +]; diff --git a/packages/deploy/deploy/400_asset/405_asset_create_setup.ts b/packages/deploy/deploy/400_asset/405_asset_create_setup.ts new file mode 100644 index 0000000000..80dedbb8c0 --- /dev/null +++ b/packages/deploy/deploy/400_asset/405_asset_create_setup.ts @@ -0,0 +1,72 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {execute, log, read, catchUnknownSigner} = deployments; + const {assetAdmin, catalystAdmin, backendAuthWallet, assetPauser} = + await getNamedAccounts(); + + const assetCreate = await deployments.get('AssetCreate'); + + const minterRole = await read('Asset', 'MINTER_ROLE'); + if (!(await read('Asset', 'hasRole', minterRole, assetCreate.address))) { + await catchUnknownSigner( + execute( + 'Asset', + {from: assetAdmin, log: true}, + 'grantRole', + minterRole, + assetCreate.address + ) + ); + log(`Asset MINTER_ROLE granted to ${assetCreate.address}`); + } + + const pauserRole = await read('AssetCreate', 'PAUSER_ROLE'); + if (!(await read('AssetCreate', 'hasRole', pauserRole, assetPauser))) { + await catchUnknownSigner( + execute( + 'AssetCreate', + {from: assetAdmin, log: true}, + 'grantRole', + pauserRole, + assetPauser + ) + ); + log(`AssetCreate PAUSER_ROLE granted to ${assetPauser}`); + } + + const catMinterRole = await read('Catalyst', 'BURNER_ROLE'); + if ( + !(await read('Catalyst', 'hasRole', catMinterRole, assetCreate.address)) + ) { + await catchUnknownSigner( + execute( + 'Catalyst', + {from: catalystAdmin, log: true}, + 'grantRole', + catMinterRole, + assetCreate.address + ) + ); + log(`Catalyst BURNER_ROLE granted to ${assetCreate.address}`); + } + + await catchUnknownSigner( + execute( + 'AuthSuperValidator', + {from: assetAdmin, log: true}, + 'setSigner', + assetCreate.address, + backendAuthWallet + ) + ); + + log(`AuthSuperValidator signer for Asset Create set to ${backendAuthWallet}`); +}; + +export default func; + +func.tags = ['Asset', 'AssetCreate', 'AssetCreate_setup']; +func.dependencies = ['Asset_deploy', 'Catalyst_deploy', 'AssetCreate_deploy']; diff --git a/packages/deploy/deploy/400_asset/406_asset_reveal_setup.ts b/packages/deploy/deploy/400_asset/406_asset_reveal_setup.ts new file mode 100644 index 0000000000..7e8fed8e22 --- /dev/null +++ b/packages/deploy/deploy/400_asset/406_asset_reveal_setup.ts @@ -0,0 +1,81 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {execute, log, read, catchUnknownSigner} = deployments; + const {assetAdmin, backendAuthWallet, assetPauser} = await getNamedAccounts(); + + const assetReveal = await deployments.get('AssetReveal'); + + const minterRole = await read('Asset', 'MINTER_ROLE'); + if (!(await read('Asset', 'hasRole', minterRole, assetReveal.address))) { + await catchUnknownSigner( + execute( + 'Asset', + {from: assetAdmin, log: true}, + 'grantRole', + minterRole, + assetReveal.address + ) + ); + log(`Asset MINTER_ROLE granted to ${assetReveal.address}`); + } + + const pauserRole = await read('AssetReveal', 'PAUSER_ROLE'); + if (!(await read('AssetReveal', 'hasRole', pauserRole, assetPauser))) { + await catchUnknownSigner( + execute( + 'AssetReveal', + {from: assetAdmin, log: true}, + 'grantRole', + pauserRole, + assetPauser + ) + ); + log(`AssetReveal PAUSER_ROLE granted to ${assetPauser}`); + } + + const burnerRole = await read('Asset', 'BURNER_ROLE'); + if (!(await read('Asset', 'hasRole', burnerRole, assetReveal.address))) { + await catchUnknownSigner( + execute( + 'Asset', + {from: assetAdmin, log: true}, + 'grantRole', + burnerRole, + assetReveal.address + ) + ); + log(`Asset BURNER_ROLE granted to ${assetReveal.address}`); + } + + await catchUnknownSigner( + execute( + 'AuthSuperValidator', + {from: assetAdmin, log: true}, + 'setSigner', + assetReveal.address, + backendAuthWallet + ) + ); + + log(`AuthSuperValidator signer for Asset Reveal set to ${backendAuthWallet}`); + + await catchUnknownSigner( + execute( + 'AssetReveal', + {from: assetAdmin, log: true}, + 'setTierInstantRevealAllowed', + 5, + true + ) + ); + + log(`Allowed instant reveal for tier 5 assets (Mythical))`); +}; + +export default func; + +func.tags = ['Asset', 'AssetReveal_setup']; +func.dependencies = ['Asset_deploy', 'AssetCreate_deploy']; diff --git a/packages/deploy/deploy/400_asset/407_asset_setup.ts b/packages/deploy/deploy/400_asset/407_asset_setup.ts new file mode 100644 index 0000000000..925488d523 --- /dev/null +++ b/packages/deploy/deploy/400_asset/407_asset_setup.ts @@ -0,0 +1,57 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; +export const DEFAULT_BPS = 300; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {execute, log, read, catchUnknownSigner} = deployments; + const {assetAdmin, contractRoyaltySetter, royaltyManagerAdmin} = + await getNamedAccounts(); + + const Asset = await deployments.get('Asset'); + + const moderatorRole = await read('Asset', 'MODERATOR_ROLE'); + if (!(await read('Asset', 'hasRole', moderatorRole, assetAdmin))) { + await catchUnknownSigner( + execute( + 'Asset', + {from: assetAdmin, log: true}, + 'grantRole', + moderatorRole, + assetAdmin + ) + ); + log(`Asset MODERATOR_ROLE granted to ${assetAdmin}`); + } + + await catchUnknownSigner( + execute( + 'RoyaltyManager', + {from: contractRoyaltySetter, log: true}, + 'setContractRoyalty', + Asset.address, + DEFAULT_BPS + ) + ); + log(`Asset set on RoyaltyManager with ${DEFAULT_BPS} BPS royalty`); + + const splitterDeployerRole = await read( + 'RoyaltyManager', + 'SPLITTER_DEPLOYER_ROLE' + ); + await catchUnknownSigner( + execute( + 'RoyaltyManager', + {from: royaltyManagerAdmin, log: true}, + 'grantRole', + splitterDeployerRole, + Asset.address + ) + ); + log(`Asset set on RoyaltyManager with Splitter Deployer Role`); +}; + +export default func; + +func.tags = ['Asset', 'Asset_setup']; +func.dependencies = ['Asset_deploy']; diff --git a/packages/deploy/deploy_mocks/200_marketplace_1.ts b/packages/deploy/deploy_mocks/200_marketplace_1.ts new file mode 100644 index 0000000000..f960ecfca7 --- /dev/null +++ b/packages/deploy/deploy_mocks/200_marketplace_1.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace1', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol:MockERC1155MarketPlace1', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace1']; diff --git a/packages/deploy/deploy_mocks/300_marketplace_2.ts b/packages/deploy/deploy_mocks/300_marketplace_2.ts new file mode 100644 index 0000000000..0e6010828c --- /dev/null +++ b/packages/deploy/deploy_mocks/300_marketplace_2.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace2', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol:MockERC1155MarketPlace2', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace2']; diff --git a/packages/deploy/deploy_mocks/400_marketplace_3.ts b/packages/deploy/deploy_mocks/400_marketplace_3.ts new file mode 100644 index 0000000000..2f846baceb --- /dev/null +++ b/packages/deploy/deploy_mocks/400_marketplace_3.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace3', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol:MockERC1155MarketPlace3', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace3']; diff --git a/packages/deploy/deploy_mocks/500_marketplace_4.ts b/packages/deploy/deploy_mocks/500_marketplace_4.ts new file mode 100644 index 0000000000..ce37a38e09 --- /dev/null +++ b/packages/deploy/deploy_mocks/500_marketplace_4.ts @@ -0,0 +1,17 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployments, getNamedAccounts} = hre; + const {deploy} = deployments; + + const {deployer} = await getNamedAccounts(); + await deploy('MockERC1155MarketPlace4', { + from: deployer, + contract: + '@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol:MockERC1155MarketPlace4', + log: true, + }); +}; +export default func; +func.tags = ['MockERC1155MarketPlace4']; diff --git a/packages/deploy/deployments/mumbai/Asset.json b/packages/deploy/deployments/mumbai/Asset.json new file mode 100644 index 0000000000..1be57c27d8 --- /dev/null +++ b/packages/deploy/deployments/mumbai/Asset.json @@ -0,0 +1,1654 @@ +{ + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "royaltyBPS", + "type": "uint16" + } + ], + "name": "DefaultRoyaltyBpsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "DefaultRoyaltyReceiverSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "OperatorFilterRegistrySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_royaltyManager", + "type": "address" + } + ], + "name": "RoyaltyManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "splitter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "RoyaltyRecipientSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "TokenRoyaltyRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "splitterAddress", + "type": "address" + } + ], + "name": "TokenRoyaltySplitterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MODERATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "burnBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "burnBatchFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllSplits", + "outputs": [ + { + "internalType": "address payable[]", + "name": "splits", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getCreatorAddress", + "outputs": [ + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getCreatorNonce", + "outputs": [ + { + "internalType": "uint16", + "name": "creatorNonce", + "type": "uint16" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getOperatorFilterRegistry", + "outputs": [ + { + "internalType": "contract IOperatorFilterRegistry", + "name": "operatorFilterRegistryAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getRecipients", + "outputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "bps", + "type": "uint16" + } + ], + "internalType": "struct Recipient[]", + "name": "recipients", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getRevealNonce", + "outputs": [ + { + "internalType": "uint16", + "name": "revealNonce", + "type": "uint16" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRoyaltyManager", + "outputs": [ + { + "internalType": "address", + "name": "managerAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getTier", + "outputs": [ + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + } + ], + "name": "getTokenIdByMetadataHash", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getTokenRoyaltiesSplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "splitterAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "hashUsed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "assetAdmin", + "type": "address" + }, + { + "internalType": "string", + "name": "baseUri", + "type": "string" + }, + { + "internalType": "address", + "name": "commonSubscription", + "type": "address" + }, + { + "internalType": "address", + "name": "_manager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isBridged", + "outputs": [ + { + "internalType": "bool", + "name": "bridged", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isRevealed", + "outputs": [ + { + "internalType": "bool", + "name": "revealed", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + } + ], + "name": "mintBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subscriptionOrRegistrantToCopy", + "type": "address" + }, + { + "internalType": "bool", + "name": "subscribe", + "type": "bool" + } + ], + "name": "registerAndSubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "royaltyInfo", + "outputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "royaltyAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "baseURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "setOperatorRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "setTokenRoyalties", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadata", + "type": "string" + } + ], + "name": "setTokenURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "supported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "tokenURI", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "transactionIndex": 11, + "gasUsed": "929195", + "logsBloom": "0x00000004000000000000000000000000400000000800000000000080100000000002000000008400000000000001000000208000002000010000000000440000000080040000000000000000000042800010008000040000040100000000000008000000020000000000020000000801000100800000000080000000000000000080010040000000000000000000000000000000000080040000000000a00000280000000000000000000000000400000000000000000000001040000400004000000020004000000001000000040200000000000400000100108000000060002000080000000000000000200002000004008000080000000000000000100000", + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2", + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "logs": [ + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000d0d6724d44381c21836ceed6d5dac14afae8f168" + ], + "data": "0x", + "logIndex": 43, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 44, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 45, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59", + "0x000000000000000000000000178fd5dec6477364d1beba000e07c18b7be61645", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 46, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x0038c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8", + "0x000000000000000000000000178fd5dec6477364d1beba000e07c18b7be61645", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 47, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de8", + "0x000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da21" + ], + "data": "0x", + "logIndex": 48, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 49, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 50, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" + ], + "data": "0x0000000000000000000000000000000000000000000000000004f3a59ada650000000000000000000000000000000000000000000000000fbfc74431548b4534000000000000000000000000000000000000000000001300a4a6dfe298a7f5f700000000000000000000000000000000000000000000000fbfc2508bb9b0e034000000000000000000000000000000000000000000001300a4abd38833825af7", + "logIndex": 51, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + } + ], + "blockNumber": 40238283, + "cumulativeGasUsed": "2740330", + "status": 1, + "byzantium": true + }, + "args": [ + "0xD0D6724D44381c21836cEed6d5DaC14aFAe8f168", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xac4a0fb600000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f700000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da210000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0x69015912aa33720b842dcd6ac059ed623f28d9f7", + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165", + "ipfs://", + "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21" + ] + }, + "implementation": "0xD0D6724D44381c21836cEed6d5DaC14aFAe8f168", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/AssetCreate.json b/packages/deploy/deployments/mumbai/AssetCreate.json new file mode 100644 index 0000000000..d02e8145f2 --- /dev/null +++ b/packages/deploy/deployments/mumbai/AssetCreate.json @@ -0,0 +1,1112 @@ +{ + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint8[]", + "name": "tiers", + "type": "uint8[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "indexed": false, + "internalType": "bool[]", + "name": "revealed", + "type": "bool[]" + } + ], + "name": "AssetBatchMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "tier", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "revealed", + "type": "bool" + } + ], + "name": "AssetMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "tier", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "revealed", + "type": "bool" + } + ], + "name": "SpecialAssetMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINT_BATCH_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SPECIAL_MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "revealed", + "type": "bool" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "createAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint8[]", + "name": "tiers", + "type": "uint8[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bool[]", + "name": "revealed", + "type": "bool[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "createMultipleAssets", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "createSpecialAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "creatorNonces", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAssetContract", + "outputs": [ + { + "internalType": "address", + "name": "assetContractAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthValidator", + "outputs": [ + { + "internalType": "address", + "name": "authValidatorAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCatalystContract", + "outputs": [ + { + "internalType": "address", + "name": "catalystContractAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_version", + "type": "string" + }, + { + "internalType": "address", + "name": "_assetContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_catalystContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_authValidator", + "type": "address" + }, + { + "internalType": "address", + "name": "_forwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultAdmin", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "signatureNonces", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "transactionIndex": 31, + "gasUsed": "898346", + "logsBloom": "0x00000004000000000000000000000000480000000000000000000080000000000002000000009400000000000001080000008000000000000000000000000000000000000000000000000000000002800000000000000000000100000000004000000000020000000000020000000800000000800000000080000000000000000000010040000000000000000000000000000000000080000000000000a0000020000000000000000000000000040000000000000000000000500000000400400000002000000000000100000004000000000000040000010010c040000020002000000000000000000000000000000004000000000000000000000000100000", + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9", + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "logs": [ + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000ed8bdb8d96d15b59d37231c520aa508c4b8b986a" + ], + "data": "0x", + "logIndex": 137, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 138, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 139, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 140, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 141, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000072e579213093600000000000000000000000000000000000000000000000fbfa9fd925ed44859000000000000000000000000000000000000000000003472aecd38c6bb3ddbe800000000000000000000000000000000000000000000000fbfa2cf3accc13f23000000000000000000000000000000000000000000003472aed4671e4d50e51e", + "logIndex": 142, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + } + ], + "blockNumber": 40238289, + "cumulativeGasUsed": "6946356", + "status": 1, + "byzantium": true + }, + "args": [ + "0xED8Bdb8D96d15B59d37231C520aa508C4B8B986a", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xc91f0c5300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000178fd5dec6477364d1beba000e07c18b7be61645000000000000000000000000059c6c226ec83742932b259153f63e333b767a5000000000000000000000000012467f6e7b23347abe0109968a9886a6c408d25a00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f700000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165000000000000000000000000000000000000000000000000000000000000001453616e64626f78204173736574204372656174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000003312e300000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "Sandbox Asset Create", + "1.0", + "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "0x059C6c226ec83742932B259153f63e333B767A50", + "0x12467f6e7b23347ABE0109968A9886A6c408d25a", + "0x69015912aa33720b842dcd6ac059ed623f28d9f7", + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165" + ] + }, + "implementation": "0xED8Bdb8D96d15B59d37231C520aa508C4B8B986a", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/AssetCreate_Implementation.json b/packages/deploy/deployments/mumbai/AssetCreate_Implementation.json new file mode 100644 index 0000000000..7709fe6fb4 --- /dev/null +++ b/packages/deploy/deployments/mumbai/AssetCreate_Implementation.json @@ -0,0 +1,1346 @@ +{ + "address": "0xED8Bdb8D96d15B59d37231C520aa508C4B8B986a", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint8[]", + "name": "tiers", + "type": "uint8[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "indexed": false, + "internalType": "bool[]", + "name": "revealed", + "type": "bool[]" + } + ], + "name": "AssetBatchMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "tier", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "revealed", + "type": "bool" + } + ], + "name": "AssetMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "tier", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "indexed": false, + "internalType": "bool", + "name": "revealed", + "type": "bool" + } + ], + "name": "SpecialAssetMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINT_BATCH_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SPECIAL_MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "revealed", + "type": "bool" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "createAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint8[]", + "name": "tiers", + "type": "uint8[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bool[]", + "name": "revealed", + "type": "bool[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "createMultipleAssets", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "createSpecialAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "creatorNonces", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAssetContract", + "outputs": [ + { + "internalType": "address", + "name": "assetContractAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthValidator", + "outputs": [ + { + "internalType": "address", + "name": "authValidatorAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCatalystContract", + "outputs": [ + { + "internalType": "address", + "name": "catalystContractAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_version", + "type": "string" + }, + { + "internalType": "address", + "name": "_assetContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_catalystContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_authValidator", + "type": "address" + }, + { + "internalType": "address", + "name": "_forwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultAdmin", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "signatureNonces", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x35e025947bbc134d9cd18a61f21852f99ac466f1621cdf777f2424ad58fd9121", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0xED8Bdb8D96d15B59d37231C520aa508C4B8B986a", + "transactionIndex": 2, + "gasUsed": "2794543", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000002000000000000000000000000000000000000000000000000000800000000000000000040100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000800000000080080000000000000200000200000000000000000000080000400000000000000000000000040000000004000000000000000000001000000040000000000000000000000108000000000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x4e67a06460f8186f7030342ad4c463987833bd2db4d7730a0d5c85b2f2bad5c8", + "transactionHash": "0x35e025947bbc134d9cd18a61f21852f99ac466f1621cdf777f2424ad58fd9121", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 40238286, + "transactionHash": "0x35e025947bbc134d9cd18a61f21852f99ac466f1621cdf777f2424ad58fd9121", + "address": "0xED8Bdb8D96d15B59d37231C520aa508C4B8B986a", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 12, + "blockHash": "0x4e67a06460f8186f7030342ad4c463987833bd2db4d7730a0d5c85b2f2bad5c8" + }, + { + "transactionIndex": 2, + "blockNumber": 40238286, + "transactionHash": "0x35e025947bbc134d9cd18a61f21852f99ac466f1621cdf777f2424ad58fd9121", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" + ], + "data": "0x000000000000000000000000000000000000000000000000001852f95716a86100000000000000000000000000000000000000000000000fbfc2508bb8bfd7d9000000000000000000000000000000000000000000001300a52eeb6f2d5e90ab00000000000000000000000000000000000000000000000fbfa9fd9261a92f78000000000000000000000000000000000000000000001300a5473e688475390c", + "logIndex": 13, + "blockHash": "0x4e67a06460f8186f7030342ad4c463987833bd2db4d7730a0d5c85b2f2bad5c8" + } + ], + "blockNumber": 40238286, + "cumulativeGasUsed": "3057130", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "a7dad225e4948fd90c6be2fd4b947044", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint8[]\",\"name\":\"tiers\",\"type\":\"uint8[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"metadataHashes\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"bool[]\",\"name\":\"revealed\",\"type\":\"bool[]\"}],\"name\":\"AssetBatchMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"tier\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"metadataHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"revealed\",\"type\":\"bool\"}],\"name\":\"AssetMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"EIP712DomainChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"tier\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"metadataHash\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"revealed\",\"type\":\"bool\"}],\"name\":\"SpecialAssetMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarderAddress\",\"type\":\"address\"}],\"name\":\"TrustedForwarderChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"TrustedForwarderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_BATCH_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PAUSER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SPECIAL_MINTER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"tier\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"revealed\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"metadataHash\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"createAsset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"uint8[]\",\"name\":\"tiers\",\"type\":\"uint8[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"bool[]\",\"name\":\"revealed\",\"type\":\"bool[]\"},{\"internalType\":\"string[]\",\"name\":\"metadataHashes\",\"type\":\"string[]\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"createMultipleAssets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"metadataHash\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"createSpecialAsset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"creatorNonces\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eip712Domain\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"fields\",\"type\":\"bytes1\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"verifyingContract\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"extensions\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAssetContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"assetContractAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAuthValidator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"authValidatorAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCatalystContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"catalystContractAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTrustedForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_version\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_assetContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_catalystContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_authValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultAdmin\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isTrustedForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"trustedForwarder\",\"type\":\"address\"}],\"name\":\"setTrustedForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"signatureNonces\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"events\":{\"EIP712DomainChanged()\":{\"details\":\"MAY be emitted to signal that the domain could have changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"RoleAdminChanged(bytes32,bytes32,bytes32)\":{\"details\":\"Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._\"},\"RoleGranted(bytes32,address,address)\":{\"details\":\"Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}.\"},\"RoleRevoked(bytes32,address,address)\":{\"details\":\"Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)\"},\"TrustedForwarderSet(address,address,address)\":{\"params\":{\"newTrustedForwarder\":\"new trusted forwarder\",\"oldTrustedForwarder\":\"old trusted forwarder\",\"operator\":\"the sender of the transaction\"}},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"createAsset(bytes,uint8,uint256,bool,string,address)\":{\"params\":{\"amount\":\"The amount of the asset to mint\",\"creator\":\"The address of the creator\",\"metadataHash\":\"The metadata hash of the asset to mint\",\"revealed\":\"Whether the asset is revealed or not\",\"signature\":\"A signature generated by TSB\",\"tier\":\"The tier of the asset to mint\"}},\"createMultipleAssets(bytes,uint8[],uint256[],bool[],string[],address)\":{\"params\":{\"amounts\":\"The amounts of the assets to mint\",\"creator\":\"The address of the creator\",\"metadataHashes\":\"The metadata hashes of the assets to mint\",\"revealed\":\"Whether the assets are revealed or not\",\"signature\":\"A signature generated by TSB\",\"tiers\":\"The tiers of the assets to mint\"}},\"createSpecialAsset(bytes,uint256,string,address)\":{\"details\":\"Only callable by the special minter\",\"params\":{\"amount\":\"The amount of the asset to mint\",\"creator\":\"The address of the creator\",\"metadataHash\":\"The metadata hash of the asset to mint,\",\"signature\":\"A signature generated by TSB\"}},\"eip712Domain()\":{\"details\":\"See {EIP-5267}. _Available since v4.9._\"},\"getAssetContract()\":{\"returns\":{\"assetContractAddress\":\"The asset contract address\"}},\"getAuthValidator()\":{\"returns\":{\"authValidatorAddress\":\"The auth validator address\"}},\"getCatalystContract()\":{\"returns\":{\"catalystContractAddress\":\"The catalyst contract address\"}},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getTrustedForwarder()\":{\"returns\":{\"_0\":\"return the address of the trusted forwarder\"}},\"grantRole(bytes32,address)\":{\"details\":\"Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event.\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"initialize(string,string,address,address,address,address,address)\":{\"params\":{\"_assetContract\":\"The address of the asset contract\",\"_authValidator\":\"The address of the AuthSuperValidator contract\",\"_catalystContract\":\"The address of the catalyst contract\",\"_defaultAdmin\":\"The address of the default admin\",\"_forwarder\":\"The address of the forwarder contract\",\"_name\":\"The name of the contract (for EIP712)\",\"_version\":\"The version of the contract (for EIP712)\"}},\"isTrustedForwarder(address)\":{\"params\":{\"forwarder\":\"trusted forwarder address to check\"},\"returns\":{\"_0\":\"true if the address is the same as the trusted forwarder\"}},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event.\"},\"revokeRole(bytes32,address)\":{\"details\":\"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event.\"},\"setTrustedForwarder(address)\":{\"details\":\"Change the address of the trusted forwarder for meta-TX\",\"params\":{\"trustedForwarder\":\"The new trustedForwarder\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"title\":\"AssetCreate\",\"version\":1},\"userdoc\":{\"events\":{\"TrustedForwarderSet(address,address,address)\":{\"notice\":\"Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\"}},\"kind\":\"user\",\"methods\":{\"createAsset(bytes,uint8,uint256,bool,string,address)\":{\"notice\":\"Create a new asset\"},\"createMultipleAssets(bytes,uint8[],uint256[],bool[],string[],address)\":{\"notice\":\"Create multiple assets at once\"},\"createSpecialAsset(bytes,uint256,string,address)\":{\"notice\":\"Create special assets, like TSB exclusive tokens\"},\"getAssetContract()\":{\"notice\":\"Get the asset contract address\"},\"getAuthValidator()\":{\"notice\":\"Get the auth validator address\"},\"getCatalystContract()\":{\"notice\":\"Get the catalyst contract address\"},\"getTrustedForwarder()\":{\"notice\":\"return the address of the trusted forwarder\"},\"initialize(string,string,address,address,address,address,address)\":{\"notice\":\"Initialize the contract\"},\"isTrustedForwarder(address)\":{\"notice\":\"return true if the forwarder is the trusted forwarder\"},\"pause()\":{\"notice\":\"Pause the contracts mint and burn functions\"},\"setTrustedForwarder(address)\":{\"notice\":\"Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\"},\"unpause()\":{\"notice\":\"Unpause the contracts mint and burn functions\"}},\"notice\":\"User-facing contract for creating new assets\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/asset/contracts/AssetCreate.sol\":\"AssetCreate\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlUpgradeable.sol\\\";\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\\n function __AccessControl_init() internal onlyInitializing {\\n }\\n\\n function __AccessControl_init_unchained() internal onlyInitializing {\\n }\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n StringsUpgradeable.toHexString(account),\\n \\\" is missing role \\\",\\n StringsUpgradeable.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xfeefb24d068524440e1ba885efdf105d91f83504af3c2d745ffacc4595396831\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControlUpgradeable {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xb8f5302f12138c5561362e88a78d061573e6298b7a1a5afe84a1e2c8d4d5aeaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\\n\\npragma solidity ^0.8.0;\\n\\ninterface IERC5267Upgradeable {\\n /**\\n * @dev MAY be emitted to signal that the domain could have changed.\\n */\\n event EIP712DomainChanged();\\n\\n /**\\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\\n * signature.\\n */\\n function eip712Domain()\\n external\\n view\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n );\\n}\\n\",\"keccak256\":\"0xe562dab443278837fa50faddb76743399e942181881db8dccaea3bd1712994db\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\\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\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\\\";\\nimport \\\"./math/SignedMathUpgradeable.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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\":\"0xb96dc79b65b7c37937919dcdb356a969ce0aa2e8338322bf4dc027a3c9c9a7eb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \\\"../StringsUpgradeable.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 ECDSAUpgradeable {\\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\\\", StringsUpgradeable.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\":\"0xa014f65d84b02827055d99993ccdbfb4b56b2c9e91eb278d82a93330659d06e4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\\n\\npragma solidity ^0.8.8;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC5267Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\\n bytes32 private constant _TYPE_HASH =\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /// @custom:oz-renamed-from _HASHED_NAME\\n bytes32 private _hashedName;\\n /// @custom:oz-renamed-from _HASHED_VERSION\\n bytes32 private _hashedVersion;\\n\\n string private _name;\\n string private _version;\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n _name = name;\\n _version = version;\\n\\n // Reset prior values in storage if upgrading\\n _hashedName = 0;\\n _hashedVersion = 0;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator();\\n }\\n\\n function _buildDomainSeparator() private view returns (bytes32) {\\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev See {EIP-5267}.\\n *\\n * _Available since v4.9._\\n */\\n function eip712Domain()\\n public\\n view\\n virtual\\n override\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n )\\n {\\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\\n // and the EIP712 domain is not reliable, as it will be missing name and version.\\n require(_hashedName == 0 && _hashedVersion == 0, \\\"EIP712: Uninitialized\\\");\\n\\n return (\\n hex\\\"0f\\\", // 01111\\n _EIP712Name(),\\n _EIP712Version(),\\n block.chainid,\\n address(this),\\n bytes32(0),\\n new uint256[](0)\\n );\\n }\\n\\n /**\\n * @dev The name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Name() internal virtual view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev The version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Version() internal virtual view returns (string memory) {\\n return _version;\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\\n */\\n function _EIP712NameHash() internal view returns (bytes32) {\\n string memory name = _EIP712Name();\\n if (bytes(name).length > 0) {\\n return keccak256(bytes(name));\\n } else {\\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\\n bytes32 hashedName = _hashedName;\\n if (hashedName != 0) {\\n return hashedName;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\\n */\\n function _EIP712VersionHash() internal view returns (bytes32) {\\n string memory version = _EIP712Version();\\n if (bytes(version).length > 0) {\\n return keccak256(bytes(version));\\n } else {\\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\\n bytes32 hashedVersion = _hashedVersion;\\n if (hashedVersion != 0) {\\n return hashedVersion;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[48] private __gap;\\n}\\n\",\"keccak256\":\"0xeb8d6be406a373771724922eb41b5d593bc8e2dc705daa22cd1145cfc8f5a3a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\\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\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\\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\":\"0x2bc0007987c229ae7624eb29be6a9b84f6a6a5872f76248b15208b131ea41c4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\\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\":\"0x88f6b7bba3ee33eeb741f9a0f5bc98b6e6e352d0fe4905377bb328590f84095a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(account),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0dd6e52cb394d7f5abe5dca2d4908a6be40417914720932de757de34a99ab87f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"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/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\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"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\"},\"@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/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\"},\"@sandbox-smart-contracts/asset/contracts/AssetCreate.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {EIP712Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\\\";\\nimport {\\n AccessControlUpgradeable,\\n ContextUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {TokenIdUtils} from \\\"./libraries/TokenIdUtils.sol\\\";\\nimport {AuthSuperValidator} from \\\"./AuthSuperValidator.sol\\\";\\nimport {\\n ERC2771HandlerUpgradeable\\n} from \\\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\\\";\\nimport {IAsset} from \\\"./interfaces/IAsset.sol\\\";\\nimport {ICatalyst} from \\\"./interfaces/ICatalyst.sol\\\";\\nimport {IAssetCreate} from \\\"./interfaces/IAssetCreate.sol\\\";\\n\\n/// @title AssetCreate\\n/// @author The Sandbox\\n/// @notice User-facing contract for creating new assets\\ncontract AssetCreate is\\n IAssetCreate,\\n Initializable,\\n ERC2771HandlerUpgradeable,\\n EIP712Upgradeable,\\n AccessControlUpgradeable,\\n PausableUpgradeable\\n{\\n using TokenIdUtils for uint256;\\n\\n IAsset private assetContract;\\n ICatalyst private catalystContract;\\n AuthSuperValidator private authValidator;\\n\\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\\n mapping(address => uint16) public creatorNonces;\\n mapping(address => uint16) public signatureNonces;\\n\\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\\\"SPECIAL_MINTER_ROLE\\\");\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n bytes32 public constant MINT_TYPEHASH =\\n keccak256(\\\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\\\");\\n bytes32 public constant MINT_BATCH_TYPEHASH =\\n keccak256(\\n \\\"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\\\"\\n );\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @notice Initialize the contract\\n /// @param _name The name of the contract (for EIP712)\\n /// @param _version The version of the contract (for EIP712)\\n /// @param _assetContract The address of the asset contract\\n /// @param _catalystContract The address of the catalyst contract\\n /// @param _authValidator The address of the AuthSuperValidator contract\\n /// @param _forwarder The address of the forwarder contract\\n /// @param _defaultAdmin The address of the default admin\\n function initialize(\\n string memory _name,\\n string memory _version,\\n address _assetContract,\\n address _catalystContract,\\n address _authValidator,\\n address _forwarder,\\n address _defaultAdmin\\n ) public initializer {\\n assetContract = IAsset(_assetContract);\\n catalystContract = ICatalyst(_catalystContract);\\n authValidator = AuthSuperValidator(_authValidator);\\n __ERC2771Handler_init(_forwarder);\\n __EIP712_init(_name, _version);\\n __AccessControl_init();\\n __Pausable_init();\\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\\n }\\n\\n /// @notice Create a new asset\\n /// @param signature A signature generated by TSB\\n /// @param tier The tier of the asset to mint\\n /// @param amount The amount of the asset to mint\\n /// @param revealed Whether the asset is revealed or not\\n /// @param metadataHash The metadata hash of the asset to mint\\n /// @param creator The address of the creator\\n function createAsset(\\n bytes memory signature,\\n uint8 tier,\\n uint256 amount,\\n bool revealed,\\n string calldata metadataHash,\\n address creator\\n ) external whenNotPaused {\\n require(\\n authValidator.verify(\\n signature,\\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\\n ),\\n \\\"AssetCreate: Invalid signature\\\"\\n );\\n\\n uint256 tokenId =\\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\\n\\n // burn catalyst of a given tier\\n catalystContract.burnFrom(creator, tier, amount);\\n assetContract.mint(creator, tokenId, amount, metadataHash);\\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\\n }\\n\\n /// @notice Create multiple assets at once\\n /// @param signature A signature generated by TSB\\n /// @param tiers The tiers of the assets to mint\\n /// @param amounts The amounts of the assets to mint\\n /// @param revealed Whether the assets are revealed or not\\n /// @param metadataHashes The metadata hashes of the assets to mint\\n /// @param creator The address of the creator\\n function createMultipleAssets(\\n bytes memory signature,\\n uint8[] calldata tiers,\\n uint256[] calldata amounts,\\n bool[] calldata revealed,\\n string[] calldata metadataHashes,\\n address creator\\n ) external whenNotPaused {\\n require(\\n authValidator.verify(\\n signature,\\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\\n ),\\n \\\"AssetCreate: Invalid signature\\\"\\n );\\n\\n require(tiers.length == amounts.length, \\\"AssetCreate: Arrays must be same length\\\");\\n require(amounts.length == metadataHashes.length, \\\"AssetCreate: Arrays must be same length\\\");\\n require(metadataHashes.length == revealed.length, \\\"AssetCreate: Arrays must be same length\\\");\\n\\n uint256[] memory tokenIds = new uint256[](tiers.length);\\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\\n for (uint256 i = 0; i < tiers.length; i++) {\\n tiersToBurn[i] = tiers[i];\\n tokenIds[i] = TokenIdUtils.generateTokenId(\\n creator,\\n tiers[i],\\n ++creatorNonces[creator],\\n revealed[i] ? 1 : 0,\\n false\\n );\\n }\\n\\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\\n\\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\\n }\\n\\n /// @notice Create special assets, like TSB exclusive tokens\\n /// @dev Only callable by the special minter\\n /// @param signature A signature generated by TSB\\n /// @param amount The amount of the asset to mint\\n /// @param metadataHash The metadata hash of the asset to mint,\\n /// @param creator The address of the creator\\n function createSpecialAsset(\\n bytes memory signature,\\n uint256 amount,\\n string calldata metadataHash,\\n address creator\\n ) external onlyRole(SPECIAL_MINTER_ROLE) whenNotPaused {\\n require(\\n authValidator.verify(\\n signature,\\n _hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash)\\n ),\\n \\\"AssetCreate: Invalid signature\\\"\\n );\\n\\n uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false);\\n\\n assetContract.mint(creator, tokenId, amount, metadataHash);\\n emit SpecialAssetMinted(creator, tokenId, 0, amount, metadataHash, true);\\n }\\n\\n /// @notice Pause the contracts mint and burn functions\\n function pause() external onlyRole(PAUSER_ROLE) {\\n _pause();\\n }\\n\\n /// @notice Unpause the contracts mint and burn functions\\n function unpause() external onlyRole(PAUSER_ROLE) {\\n _unpause();\\n }\\n\\n /// @notice Get the asset contract address\\n /// @return assetContractAddress The asset contract address\\n function getAssetContract() external view returns (address assetContractAddress) {\\n return address(assetContract);\\n }\\n\\n /// @notice Get the catalyst contract address\\n /// @return catalystContractAddress The catalyst contract address\\n function getCatalystContract() external view returns (address catalystContractAddress) {\\n return address(catalystContract);\\n }\\n\\n /// @notice Get the auth validator address\\n /// @return authValidatorAddress The auth validator address\\n function getAuthValidator() external view returns (address authValidatorAddress) {\\n return address(authValidator);\\n }\\n\\n /// @notice Creates a hash of the mint data\\n /// @param creator The address of the creator\\n /// @param nonce The nonce of the creator\\n /// @param tier The tier of the asset\\n /// @param amount The amount of copies to mint\\n /// @param revealed Whether the asset is revealed or not\\n /// @param metadataHash The metadata hash of the asset\\n /// @return digest The hash of the mint data\\n function _hashMint(\\n address creator,\\n uint16 nonce,\\n uint8 tier,\\n uint256 amount,\\n bool revealed,\\n string calldata metadataHash\\n ) internal view returns (bytes32 digest) {\\n digest = _hashTypedDataV4(\\n keccak256(\\n abi.encode(\\n MINT_TYPEHASH,\\n creator,\\n nonce,\\n tier,\\n amount,\\n revealed,\\n keccak256((abi.encodePacked(metadataHash)))\\n )\\n )\\n );\\n }\\n\\n /// @notice Creates a hash of the mint batch data\\n /// @param creator The address of the creator\\n /// @param nonce The nonce of the creator\\n /// @param tiers The tiers of the assets\\n /// @param amounts The amounts of copies to mint\\n /// @param revealed Whether the assets are revealed or not\\n /// @param metadataHashes The metadata hashes of the assets\\n /// @return digest The hash of the mint batch data\\n function _hashBatchMint(\\n address creator,\\n uint16 nonce,\\n uint8[] calldata tiers,\\n uint256[] calldata amounts,\\n bool[] calldata revealed,\\n string[] calldata metadataHashes\\n ) internal view returns (bytes32 digest) {\\n digest = _hashTypedDataV4(\\n keccak256(\\n abi.encode(\\n MINT_BATCH_TYPEHASH,\\n creator,\\n nonce,\\n keccak256(abi.encodePacked(tiers)),\\n keccak256(abi.encodePacked(amounts)),\\n keccak256(abi.encodePacked(revealed)),\\n _encodeHashes(metadataHashes)\\n )\\n )\\n );\\n }\\n\\n /// @notice Encodes the hashes of the metadata for signature verification\\n /// @param metadataHashes The hashes of the metadata\\n /// @return encodedHashes The encoded hashes of the metadata\\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\\n for (uint256 i = 0; i < metadataHashes.length; i++) {\\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\\n }\\n\\n return keccak256(abi.encodePacked(encodedHashes));\\n }\\n\\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\\n /// @dev Change the address of the trusted forwarder for meta-TX\\n /// @param trustedForwarder The new trustedForwarder\\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(trustedForwarder != address(0), \\\"AssetCreate: Zero address\\\");\\n _setTrustedForwarder(trustedForwarder);\\n }\\n\\n function _msgSender()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (address sender)\\n {\\n return ERC2771HandlerUpgradeable._msgSender();\\n }\\n\\n function _msgData()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (bytes calldata)\\n {\\n return ERC2771HandlerUpgradeable._msgData();\\n }\\n\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0xcb31c361ad3c9b19a91094aa54b48e582e161436b7c533b75ef4e94e13648fd0\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {AccessControl} from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\n\\n/// @title AuthSuperValidator\\n/// @author The Sandbox\\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\\ncontract AuthSuperValidator is AccessControl {\\n mapping(address => address) private _signers;\\n\\n /// @dev Constructor\\n /// @param admin Address of the admin that will be able to grant roles\\n constructor(address admin) {\\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\\n }\\n\\n /// @notice Sets the signer for a contract\\n /// @dev Only the admin can call this function\\n /// @param contractAddress Address of the contract to set the signer for\\n /// @param signer Address of the signer\\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\\n _signers[contractAddress] = signer;\\n }\\n\\n /// @notice Gets the signer for a contract\\n /// @param contractAddress Address of the contract to get the signer for\\n /// @return address of the signer\\n function getSigner(address contractAddress) public view returns (address) {\\n return _signers[contractAddress];\\n }\\n\\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\\n /// @dev Multipurpose function that can be used to verify signatures with different digests\\n /// @param signature Signature hash\\n /// @param digest Digest hash\\n /// @return bool\\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\\n address signer = _signers[_msgSender()];\\n require(signer != address(0), \\\"AuthSuperValidator: No signer\\\");\\n address recoveredSigner = ECDSA.recover(digest, signature);\\n return recoveredSigner == signer;\\n }\\n\\n /// @notice Prevents the DEFAULT_ADMIN_ROLE from being renounced\\n /// @dev This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced\\n /// @param role Role to renounce\\n /// @param account Account to renounce the role for\\n function renounceRole(bytes32 role, address account) public override {\\n require(role != DEFAULT_ADMIN_ROLE, \\\"AuthSuperValidator: cant renounce admin role\\\");\\n super.renounceRole(role, account);\\n }\\n}\\n\",\"keccak256\":\"0xd285d5edbc7bedd8dbc3341af44c05ff3bc204ec2e4b6d7bffcd9bb91de3f141\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/// @title Asset interface\\n/// @author The Sandbox\\ninterface IAsset {\\n // AssetData reflects the asset tokenId structure\\n // Refer to TokenIdUtils.sol\\n struct AssetData {\\n uint256 tokenId;\\n address creator;\\n uint256 amount;\\n uint8 tier;\\n uint16 creatorNonce;\\n bool revealed;\\n string metadataHash;\\n bool bridged;\\n }\\n\\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\\n\\n /// @notice Mint new tokens\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param id The id of the token to mint\\n /// @param amount The amount of the token to mint\\n /// @param metadataHash The metadata hash of the token to mint\\n function mint(\\n address to,\\n uint256 id,\\n uint256 amount,\\n string memory metadataHash\\n ) external;\\n\\n /// @notice Mint new tokens with catalyst tier chosen by the creator\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param ids The ids of the tokens to mint\\n /// @param amounts The amounts of the tokens to mint\\n /// @param metadataHashes The metadata hashes of the tokens to mint\\n function mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n string[] memory metadataHashes\\n ) external;\\n\\n /// @notice Burn a token from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @param account The account to burn tokens from\\n /// @param id The token id to burn\\n /// @param amount The amount of tokens to burn\\n function burnFrom(\\n address account,\\n uint256 id,\\n uint256 amount\\n ) external;\\n\\n /// @notice Burn a batch of tokens from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @dev The length of the ids and amounts arrays must be the same\\n /// @param account The account to burn tokens from\\n /// @param ids An array of token ids to burn\\n /// @param amounts An array of amounts of tokens to burn\\n function burnBatchFrom(\\n address account,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external;\\n\\n /// @notice returns the tokenId associated with provided metadata hash\\n /// @param metadataHash The metadata hash to get tokenId for\\n /// @return tokenId the tokenId associated with the metadata hash\\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256 tokenId);\\n}\\n\",\"keccak256\":\"0xbc79058becff31b0b7f465d92a89aad25f561dbdb5a2cd068d51c7ef93b4fbfe\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/// @title AssetCreate interface\\n/// @author The Sandbox\\ninterface IAssetCreate {\\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\\n event AssetMinted(\\n address indexed creator,\\n uint256 tokenId,\\n uint16 tier,\\n uint256 amount,\\n string metadataHash,\\n bool revealed\\n );\\n event SpecialAssetMinted(\\n address indexed creator,\\n uint256 tokenId,\\n uint16 tier,\\n uint256 amount,\\n string metadataHash,\\n bool revealed\\n );\\n event AssetBatchMinted(\\n address indexed creator,\\n uint256[] tokenIds,\\n uint8[] tiers,\\n uint256[] amounts,\\n string[] metadataHashes,\\n bool[] revealed\\n );\\n}\\n\",\"keccak256\":\"0x3d5d85ce6ad96f56d2d39e191d851ec82acd41e69e1658af97affb9aa522bca7\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\ninterface ICatalyst {\\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\\n\\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\\n event NewCatalystTypeAdded(uint256 catalystId);\\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\\n event BaseURISet(string baseURI);\\n event OperatorRegistrySet(address indexed registry);\\n\\n /// @notice Mints a new token, limited to MINTER_ROLE only\\n /// @param to The address that will own the minted token\\n /// @param id The token id to mint\\n /// @param amount The amount to be minted\\n function mint(\\n address to,\\n uint256 id,\\n uint256 amount\\n ) external;\\n\\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\\n /// @param to The address that will own the minted tokens\\n /// @param ids The token ids to mint\\n /// @param amounts The amounts to be minted per token id\\n function mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external;\\n\\n /// @notice Burns a specified amount of tokens from a specific address\\n /// @param account The address to burn from\\n /// @param id The token id to burn\\n /// @param amount The amount to be burned\\n function burnFrom(\\n address account,\\n uint256 id,\\n uint256 amount\\n ) external;\\n\\n /// @notice Burns a batch of tokens from a specific address\\n /// @param account The address to burn from\\n /// @param ids The token ids to burn\\n /// @param amounts The amounts to be burned\\n function burnBatchFrom(\\n address account,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external;\\n\\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\\n /// @param ipfsCID The royalty bps for the catalyst\\n function addNewCatalystType(string memory ipfsCID) external;\\n\\n /// @notice Set a new URI for specific tokenid\\n /// @param tokenId The token id to set URI for\\n /// @param metadataHash The new URI\\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\\n\\n /// @notice Set a new base URI\\n /// @param baseURI The new base URI\\n function setBaseURI(string memory baseURI) external;\\n}\\n\",\"keccak256\":\"0x4dec39e4b662c4b51f0f828f1b8ea01c873c8a0a18a7c17bc5497f557ceff101\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IAsset} from \\\"../interfaces/IAsset.sol\\\";\\n\\n/// @title TokenIdUtils library\\n/// @author The Sandbox\\n/// @notice Contains utility functions for token ids\\nlibrary TokenIdUtils {\\n // Layer masks\\n uint256 public constant TIER_MASK = 0xFF;\\n uint256 public constant NONCE_MASK = 0xFFFF;\\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\\n uint256 public constant BRIDGED_MASK = 0x1;\\n\\n // Bit shifts\\n uint256 public constant CREATOR_SHIFT = 0;\\n uint256 public constant TIER_SHIFT = 160;\\n uint256 public constant NONCE_SHIFT = 168;\\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\\n uint256 public constant BRIDGED_SHIFT = 200;\\n\\n /// @notice Generates a token id for a given asset\\n /// @dev The token id is generated by concatenating the following fields:\\n /// @dev creator address, tier, creator nonce, reveal nonce and bridged boolean\\n /// @dev The first 160 bits are the creator address\\n /// @dev The next 8 bits are the tier\\n /// @dev The next 16 bits are the creator nonce\\n /// @dev The next 16 bits are for reveal nonce.\\n /// @dev The last bit is for bridged boolean\\n /// @param creator The address of the creator of the asset\\n /// @param tier The tier of the asset determined by the catalyst used to create it\\n /// @param creatorNonce The nonce of the asset creator\\n /// @param revealNonce The reveal nonce of the asset\\n /// @param bridged Whether the asset is bridged or not\\n /// @return tokenId The generated token id\\n function generateTokenId(\\n address creator,\\n uint8 tier,\\n uint16 creatorNonce,\\n uint16 revealNonce,\\n bool bridged\\n ) internal pure returns (uint256 tokenId) {\\n uint160 creatorAddress = uint160(creator);\\n\\n tokenId = tokenId =\\n uint256(creatorAddress) |\\n (uint256(tier) << TIER_SHIFT) |\\n (uint256(creatorNonce) << NONCE_SHIFT) |\\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\\n\\n return tokenId;\\n }\\n\\n /// @notice Extracts the creator address from a given token id\\n /// @param tokenId The token id to extract the creator address from\\n /// @return creator The asset creator address\\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\\n creator = address(uint160(tokenId));\\n return creator;\\n }\\n\\n /// @notice Extracts the tier from a given token id\\n /// @param tokenId The token id to extract the tier from\\n /// @return tier The asset tier, determined by the catalyst used to create it\\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\\n return tier;\\n }\\n\\n /// @notice Extracts the revealed flag from a given token id\\n /// @param tokenId The token id to extract the revealed flag from\\n /// @return isRevealed Whether the asset is revealed or not\\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\\n uint16 revealNonce = getRevealNonce(tokenId);\\n return revealNonce != 0;\\n }\\n\\n /// @notice Extracts the asset nonce from a given token id\\n /// @param tokenId The token id to extract the asset nonce from\\n /// @return creatorNonce The asset creator nonce\\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\\n return creatorNonce;\\n }\\n\\n /// @notice Extracts the abilities and enhancements hash from a given token id\\n /// @param tokenId The token id to extract reveal nonce from\\n /// @return revealNonce The reveal nonce of the asset\\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\\n return revealNonce;\\n }\\n\\n /// @notice Extracts the bridged flag from a given token id\\n /// @param tokenId The token id to extract the bridged flag from\\n /// @return bridged Whether the asset is bridged or not\\n function isBridged(uint256 tokenId) internal pure returns (bool) {\\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\\n return bridged;\\n }\\n\\n /// @notice Extracts the asset data from a given token id\\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\\n /// @param tokenId The token id to extract the asset data from\\n /// @return data The asset data struct\\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\\n data.creator = getCreatorAddress(tokenId);\\n data.tier = getTier(tokenId);\\n data.revealed = isRevealed(tokenId);\\n data.creatorNonce = getCreatorNonce(tokenId);\\n data.bridged = isBridged(tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x68a7d6f1ff700f2c1cc9b20e89ccd9aa7fced45a54cc1e3c361136c57d0e4511\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\nabstract contract ERC2771HandlerAbstract {\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function isTrustedForwarder(address forwarder) external view returns (bool) {\\n return _isTrustedForwarder(forwarder);\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual returns (address sender) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n // The assembly code is more direct than the Solidity version using `abi.decode`.\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\\n }\\n } else {\\n sender = msg.sender;\\n }\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual returns (bytes calldata) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n return msg.data[:msg.data.length - 20];\\n } else {\\n return msg.data;\\n }\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n /// @dev this function must be IMPLEMENTED\\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xc4f349865ea7146f51b69f1edacdef60e0a2a7cf4dab538a5ae53ee9a0036231\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {ERC2771HandlerAbstract} from \\\"./ERC2771HandlerAbstract.sol\\\";\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\\n address private _trustedForwarder;\\n\\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\\n /// @param oldTrustedForwarder old trusted forwarder\\n /// @param newTrustedForwarder new trusted forwarder\\n /// @param operator the sender of the transaction\\n event TrustedForwarderSet(\\n address indexed oldTrustedForwarder,\\n address indexed newTrustedForwarder,\\n address indexed operator\\n );\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\\n __ERC2771Handler_init_unchained(forwarder);\\n }\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\\n _setTrustedForwarder(forwarder);\\n }\\n\\n /// @notice return the address of the trusted forwarder\\n /// @return return the address of the trusted forwarder\\n function getTrustedForwarder() external view returns (address) {\\n return _trustedForwarder;\\n }\\n\\n /// @notice set the address of the trusted forwarder\\n /// @param newForwarder the address of the new forwarder.\\n function _setTrustedForwarder(address newForwarder) internal virtual {\\n require(newForwarder != _trustedForwarder, \\\"ERC2771HandlerUpgradeable: forwarder already set\\\");\\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\\n _trustedForwarder = newForwarder;\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\\n return forwarder == _trustedForwarder;\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual override returns (address sender) {\\n return super._msgSender();\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual override returns (bytes calldata) {\\n return super._msgData();\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf9767f843906800128ee86bd89bc2088e8f1b633ed4c800f477beb4e604f81de\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61313c80620000f36000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80638456cb59116100f9578063d547741f11610097578063dbd8483d11610071578063dbd8483d146103fb578063de743a7214610420578063e63ab1e914610447578063f76fc35e1461046e57600080fd5b8063d547741f146103c3578063d5f2077c146103d6578063da742228146103e857600080fd5b80639e7495aa116100d35780639e7495aa1461037e578063a217fddf14610391578063c91f0c5314610399578063ce1b815f146103ac57600080fd5b80638456cb591461032257806384b0196e1461032a57806391d148541461034557600080fd5b806336568abe1161016657806359c191e41161014057806359c191e4146102b85780635c975abb146102de57806374e3447a146102e95780637caa719a1461031057600080fd5b806336568abe1461028a5780633f4ba83a1461029d578063572b6c05146102a557600080fd5b80632d94a9d3116101975780632d94a9d31461022c5780632f2ff15d1461023f57806334dcdd521461025257600080fd5b806301ffc9a7146101be5780631a3101b1146101e6578063248a9ca3146101fb575b600080fd5b6101d16101cc366004612358565b610495565b60405190151581526020015b60405180910390f35b6101f96101f43660046124d5565b61052e565b005b61021e61020936600461257f565b600090815260ca602052604090206001015490565b6040519081526020016101dd565b6101f961023a366004612598565b610821565b6101f961024d36600461261d565b610aa2565b610277610260366004612649565b6101316020526000908152604090205461ffff1681565b60405161ffff90911681526020016101dd565b6101f961029836600461261d565b610acc565b6101f9610b68565b6101d16102b3366004612649565b610b9d565b61012e546001600160a01b03165b6040516001600160a01b0390911681526020016101dd565b60fc5460ff166101d1565b61021e7fb696df569c2dfecb5a24edfd39d7f55b0f442be14350cbc68dbe8eb35489d3a681565b61012f546001600160a01b03166102c6565b6101f9610bba565b610332610bec565b6040516101dd97969594939291906126ef565b6101d161035336600461261d565b600091825260ca602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6101f961038c3660046127be565b610cae565b61021e600081565b6101f96103a73660046128b7565b61120c565b6000546201000090046001600160a01b03166102c6565b6101f96103d136600461261d565b6113b1565b610130546001600160a01b03166102c6565b6101f96103f6366004612649565b6113d6565b610277610409366004612649565b6101326020526000908152604090205461ffff1681565b61021e7f52955c021a90f71f7afee289089576ce6998f456ca81e444651c71363bf2609581565b61021e7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b61021e7f3b0c69bab62d38b5774be9b5185349bf525ef97a4d288b652e29bb4ec2a4902d81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061052857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b610536611440565b610130546001600160a01b0316636b406341886105a984610132600061055a611495565b6001600160a01b0316815260208101919091526040016000908120805461ffff169161058583612976565b91906101000a81548161ffff021916908361ffff1602179055508b8b8b8b8b6114a4565b6040518363ffffffff1660e01b81526004016105c6929190612997565b602060405180830381865afa1580156105e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060791906129b9565b6106585760405162461bcd60e51b815260206004820152601e60248201527f41737365744372656174653a20496e76616c6964207369676e6174757265000060448201526064015b60405180910390fd5b6001600160a01b03811660009081526101316020526040812080546106bd9184918a9190859061068b9061ffff16612976565b91906101000a81548161ffff021916908361ffff1602179055886106b05760006106b3565b60015b60ff166000611568565b61012f546040517f124d91e50000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260ff8b166024830152604482018a905292935091169063124d91e590606401600060405180830381600087803b15801561073057600080fd5b505af1158015610744573d6000803e3d6000fd5b505061012e546040517fbb7fde710000000000000000000000000000000000000000000000000000000081526001600160a01b03909116925063bb7fde71915061079a90859085908b908a908a90600401612a01565b600060405180830381600087803b1580156107b457600080fd5b505af11580156107c8573d6000803e3d6000fd5b50505050816001600160a01b03167f293c16277edbc93bfb30f56ac279e45bbdbd421755b0278d19ebcd1cee6a795b82898988888b60405161080f96959493929190612a3b565b60405180910390a25050505050505050565b7fb696df569c2dfecb5a24edfd39d7f55b0f442be14350cbc68dbe8eb35489d3a661084b816115b5565b610853611440565b610130546001600160a01b0316636b406341876108c8856101326000610877611495565b6001600160a01b0316815260208101919091526040016000908120805461ffff16916108a283612976565b91906101000a81548161ffff021916908361ffff16021790555060008b60018c8c6114a4565b6040518363ffffffff1660e01b81526004016108e5929190612997565b602060405180830381865afa158015610902573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092691906129b9565b6109725760405162461bcd60e51b815260206004820152601e60248201527f41737365744372656174653a20496e76616c6964207369676e61747572650000604482015260640161064f565b6001600160a01b03821660009081526101316020526040812080546109c791859184919082906109a59061ffff16612976565b91906101000a81548161ffff021916908361ffff160217905560016000611568565b61012e546040517fbb7fde710000000000000000000000000000000000000000000000000000000081529192506001600160a01b03169063bb7fde7190610a1a90869085908b908b908b90600401612a01565b600060405180830381600087803b158015610a3457600080fd5b505af1158015610a48573d6000803e3d6000fd5b50505050826001600160a01b03167f07560e268a00bce229c6a07c00d3f177f67674deae28b79a1840dd20712366288260008989896001604051610a9196959493929190612a79565b60405180910390a250505050505050565b600082815260ca6020526040902060010154610abd816115b5565b610ac783836115c6565b505050565b610ad4611495565b6001600160a01b0316816001600160a01b031614610b5a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161064f565b610b648282611669565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b92816115b5565b610b9a61170a565b50565b600080546001600160a01b03838116620100009092041614610528565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610be4816115b5565b610b9a611762565b6000606080600080600060606032546000801b148015610c0c5750603354155b610c585760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a65640000000000000000000000604482015260640161064f565b610c606117a0565b610c68611832565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b610cb6611440565b610130546001600160a01b0316636b4063418b610d2c846101326000610cda611495565b6001600160a01b0316815260208101919091526040016000908120805461ffff1691610d0583612976565b91906101000a81548161ffff021916908361ffff1602179055508e8e8e8e8e8e8e8e611841565b6040518363ffffffff1660e01b8152600401610d49929190612997565b602060405180830381865afa158015610d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8a91906129b9565b610dd65760405162461bcd60e51b815260206004820152601e60248201527f41737365744372656174653a20496e76616c6964207369676e61747572650000604482015260640161064f565b878614610e355760405162461bcd60e51b815260206004820152602760248201527f41737365744372656174653a20417272617973206d7573742062652073616d65604482015266040d8cadccee8d60cb1b606482015260840161064f565b858214610e945760405162461bcd60e51b815260206004820152602760248201527f41737365744372656174653a20417272617973206d7573742062652073616d65604482015266040d8cadccee8d60cb1b606482015260840161064f565b818414610ef35760405162461bcd60e51b815260206004820152602760248201527f41737365744372656174653a20417272617973206d7573742062652073616d65604482015266040d8cadccee8d60cb1b606482015260840161064f565b60008867ffffffffffffffff811115610f0e57610f0e61239a565b604051908082528060200260200182016040528015610f37578160200160208202803683370190505b50905060008967ffffffffffffffff811115610f5557610f5561239a565b604051908082528060200260200182016040528015610f7e578160200160208202803683370190505b50905060005b8a8110156110a4578b8b82818110610f9e57610f9e612aa3565b9050602002016020810190610fb39190612ab9565b60ff16828281518110610fc857610fc8612aa3565b602002602001018181525050611075848d8d84818110610fea57610fea612aa3565b9050602002016020810190610fff9190612ab9565b6001600160a01b038716600090815261013160205260408120805490919061102a9061ffff16612976565b91906101000a81548161ffff021916908361ffff16021790558b8b8681811061105557611055612aa3565b905060200201602081019061106a9190612ad4565b6106b05760006106b3565b83828151811061108757611087612aa3565b60209081029190910101528061109c81612af1565b915050610f84565b5061012f546040517f20820ec30000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906320820ec3906110f590869085908e908e90600401612b56565b600060405180830381600087803b15801561110f57600080fd5b505af1158015611123573d6000803e3d6000fd5b505061012e546040517fa55784ef0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116925063a55784ef915061117b90869086908e908e908c908c90600401612c3b565b600060405180830381600087803b15801561119557600080fd5b505af11580156111a9573d6000803e3d6000fd5b50505050826001600160a01b03167fdd4b554190cbd4759e711abb655bdaf12557fea0ac84cec4fd4d978db3148bab838d8d8d8d8b8b8f8f6040516111f699989796959493929190612c92565b60405180910390a2505050505050505050505050565b600054610100900460ff161580801561122c5750600054600160ff909116105b806112465750303b158015611246575060005460ff166001145b6112b85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161064f565b6000805460ff1916600117905580156112db576000805461ff0019166101001790555b61012e80546001600160a01b038089167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925561012f805488841690831617905561013080549287169290911691909117905561133c83611950565b61134688886119c4565b61134e611a39565b611356611aa4565b6113616000836115c6565b80156113a7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b600082815260ca60205260409020600101546113cc816115b5565b610ac78383611669565b60006113e1816115b5565b6001600160a01b0382166114375760405162461bcd60e51b815260206004820152601960248201527f41737365744372656174653a205a65726f206164647265737300000000000000604482015260640161064f565b610b6482611b17565b60fc5460ff16156114935760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161064f565b565b600061149f611c2c565b905090565b600061155c7f3b0c69bab62d38b5774be9b5185349bf525ef97a4d288b652e29bb4ec2a4902d898989898989896040516020016114e2929190612d57565b60408051601f198184030181528282528051602091820120908301989098526001600160a01b039096169581019590955261ffff909316606085015260ff909116608084015260a0830152151560c082015260e0810191909152610100015b60405160208183030381529060405280519060200120611c36565b98975050505050505050565b60008560c88361157957600061157c565b60015b60ff16901b60b88561ffff16901b60a88761ffff16901b60a08960ff16901b846001600160a01b03161717171791505095945050505050565b610b9a816115c1611495565b611c7e565b600082815260ca602090815260408083206001600160a01b038516845290915290205460ff16610b6457600082815260ca602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611625611495565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260ca602090815260408083206001600160a01b038516845290915290205460ff1615610b6457600082815260ca602090815260408083206001600160a01b03851684529091529020805460ff191690556116c6611495565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b611712611cf3565b60fc805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611745611495565b6040516001600160a01b03909116815260200160405180910390a1565b61176a611440565b60fc805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611745611495565b6060603480546117af90612d67565b80601f01602080910402602001604051908101604052809291908181526020018280546117db90612d67565b80156118285780601f106117fd57610100808354040283529160200191611828565b820191906000526020600020905b81548152906001019060200180831161180b57829003601f168201915b5050505050905090565b6060603580546117af90612d67565b60006119417f52955c021a90f71f7afee289089576ce6998f456ca81e444651c71363bf260958c8c8c8c60405160200161187c929190612da1565b604051602081830303815290604052805190602001208b8b6040516020016118a5929190612ddb565b604051602081830303815290604052805190602001208a8a6040516020016118ce929190612e1d565b60408051601f1981840301815291905280516020909101206118f86118f38a8c612e4d565b611d45565b6040805160208101989098526001600160a01b039096169587019590955261ffff9093166060860152608085019190915260a084015260c083015260e082015261010001611541565b9b9a5050505050505050505050565b600054610100900460ff166119bb5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b610b9a81611e39565b600054610100900460ff16611a2f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b610b648282611ead565b600054610100900460ff166114935760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b600054610100900460ff16611b0f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b611493611f40565b6000546001600160a01b0362010000909104811690821603611ba15760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c72656164792073657400000000000000000000000000000000606482015260840161064f565b611ba9611495565b600080546040516001600160a01b0393841693858116936201000090930416917f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e591a4600080546001600160a01b0390921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b600061149f611fb7565b6000610528611c4361200e565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b600082815260ca602090815260408083206001600160a01b038516845290915290205460ff16610b6457611cb181612018565b611cbc83602061202a565b604051602001611ccd929190612ed1565b60408051601f198184030181529082905262461bcd60e51b825261064f91600401612f52565b60fc5460ff166114935760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161064f565b600080825167ffffffffffffffff811115611d6257611d6261239a565b604051908082528060200260200182016040528015611d8b578160200160208202803683370190505b50905060005b8351811015611e0957838181518110611dac57611dac612aa3565b6020026020010151604051602001611dc49190612f65565b60405160208183030381529060405280519060200120828281518110611dec57611dec612aa3565b602090810291909101015280611e0181612af1565b915050611d91565b5080604051602001611e1b9190612f81565b60405160208183030381529060405280519060200120915050919050565b600054610100900460ff16611ea45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b610b9a81611b17565b600054610100900460ff16611f185760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b6034611f248382613005565b506035611f318282613005565b50506000603281905560335550565b600054610100900460ff16611fab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b60fc805460ff19169055565b600080546201000090046001600160a01b031633148015611fd9575060143610155b1561200957507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600061149f61225a565b60606105286001600160a01b03831660145b606060006120398360026130c5565b6120449060026130dc565b67ffffffffffffffff81111561205c5761205c61239a565b6040519080825280601f01601f191660200182016040528015612086576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106120bd576120bd612aa3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061212057612120612aa3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061215c8460026130c5565b6121679060016130dc565b90505b6001811115612204577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106121a8576121a8612aa3565b1a60f81b8282815181106121be576121be612aa3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936121fd816130ef565b905061216a565b5083156122535760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161064f565b9392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6122856122ce565b61228d612327565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6000806122d96117a0565b8051909150156122f0578051602090910120919050565b60325480156122ff5792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b600080612332611832565b805190915015612349578051602090910120919050565b60335480156122ff5792915050565b60006020828403121561236a57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461225357600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156123d9576123d961239a565b604052919050565b600082601f8301126123f257600080fd5b813567ffffffffffffffff81111561240c5761240c61239a565b61241f6020601f19601f840116016123b0565b81815284602083860101111561243457600080fd5b816020850160208301376000918101602001919091529392505050565b803560ff8116811461246257600080fd5b919050565b8015158114610b9a57600080fd5b60008083601f84011261248757600080fd5b50813567ffffffffffffffff81111561249f57600080fd5b6020830191508360208285010111156124b757600080fd5b9250929050565b80356001600160a01b038116811461246257600080fd5b600080600080600080600060c0888a0312156124f057600080fd5b873567ffffffffffffffff8082111561250857600080fd5b6125148b838c016123e1565b985061252260208b01612451565b975060408a0135965060608a0135915061253b82612467565b9094506080890135908082111561255157600080fd5b5061255e8a828b01612475565b9094509250612571905060a089016124be565b905092959891949750929550565b60006020828403121561259157600080fd5b5035919050565b6000806000806000608086880312156125b057600080fd5b853567ffffffffffffffff808211156125c857600080fd5b6125d489838a016123e1565b96506020880135955060408801359150808211156125f157600080fd5b506125fe88828901612475565b90945092506126119050606087016124be565b90509295509295909350565b6000806040838503121561263057600080fd5b82359150612640602084016124be565b90509250929050565b60006020828403121561265b57600080fd5b612253826124be565b60005b8381101561267f578181015183820152602001612667565b50506000910152565b600081518084526126a0816020860160208601612664565b601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b838110156126e4578151875295820195908201906001016126c8565b509495945050505050565b7fff000000000000000000000000000000000000000000000000000000000000008816815260e06020820152600061272a60e0830189612688565b828103604084015261273c8189612688565b90508660608401526001600160a01b03861660808401528460a084015282810360c084015261276b81856126b4565b9a9950505050505050505050565b60008083601f84011261278b57600080fd5b50813567ffffffffffffffff8111156127a357600080fd5b6020830191508360208260051b85010111156124b757600080fd5b60008060008060008060008060008060c08b8d0312156127dd57600080fd5b8a3567ffffffffffffffff808211156127f557600080fd5b6128018e838f016123e1565b9b5060208d013591508082111561281757600080fd5b6128238e838f01612779565b909b50995060408d013591508082111561283c57600080fd5b6128488e838f01612779565b909950975060608d013591508082111561286157600080fd5b61286d8e838f01612779565b909750955060808d013591508082111561288657600080fd5b506128938d828e01612779565b90945092506128a6905060a08c016124be565b90509295989b9194979a5092959850565b600080600080600080600060e0888a0312156128d257600080fd5b873567ffffffffffffffff808211156128ea57600080fd5b6128f68b838c016123e1565b985060208a013591508082111561290c57600080fd5b506129198a828b016123e1565b965050612928604089016124be565b9450612936606089016124be565b9350612944608089016124be565b925061295260a089016124be565b915061257160c089016124be565b634e487b7160e01b600052601160045260246000fd5b600061ffff80831681810361298d5761298d612960565b6001019392505050565b6040815260006129aa6040830185612688565b90508260208301529392505050565b6000602082840312156129cb57600080fd5b815161225381612467565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6001600160a01b0386168152846020820152836040820152608060608201526000612a306080830184866129d6565b979650505050505050565b86815260ff8616602082015284604082015260a060608201526000612a6460a0830185876129d6565b90508215156080830152979650505050505050565b86815261ffff8616602082015284604082015260a060608201526000612a6460a0830185876129d6565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612acb57600080fd5b61225382612451565b600060208284031215612ae657600080fd5b813561225381612467565b60006000198203612b0457612b04612960565b5060010190565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612b3d57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0385168152606060208201526000612b7860608301866126b4565b8281036040840152612a30818587612b0b565b81835260006020808501808196508560051b810191508460005b87811015612c2e57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1883603018112612be457600080fd5b8701858101903567ffffffffffffffff811115612c0057600080fd5b803603821315612c0f57600080fd5b612c1a8682846129d6565b9a87019a9550505090840190600101612ba5565b5091979650505050505050565b6001600160a01b0387168152608060208201526000612c5d60808301886126b4565b8281036040840152612c70818789612b0b565b90508281036060840152612c85818587612b8b565b9998505050505050505050565b60a081526000612ca560a083018c6126b4565b8281036020848101919091528a82528b91810160005b8c811015612ce15760ff612cce85612451565b1682529282019290820190600101612cbb565b508481036040860152612cf5818b8d612b0b565b9250508382036060850152612d0b82888a612b8b565b8481036080860152858152869250810160005b86811015612d45578335612d3181612467565b151582529282019290820190600101612d1e565b509d9c50505050505050505050505050565b8183823760009101908152919050565b600181811c90821680612d7b57607f821691505b602082108103612d9b57634e487b7160e01b600052602260045260246000fd5b50919050565b60008184825b85811015612dd05760ff612dba83612451565b1683526020928301929190910190600101612da7565b509095945050505050565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612e0a57600080fd5b8260051b80858437919091019392505050565b60008184825b85811015612dd0578135612e3681612467565b151583526020928301929190910190600101612e23565b600067ffffffffffffffff80841115612e6857612e6861239a565b8360051b6020612e798183016123b0565b868152918501918181019036841115612e9157600080fd5b865b84811015612ec557803586811115612eab5760008081fd5b612eb736828b016123e1565b845250918301918301612e93565b50979650505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612f09816017850160208801612664565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351612f46816028840160208801612664565b01602801949350505050565b6020815260006122536020830184612688565b60008251612f77818460208701612664565b9190910192915050565b815160009082906020808601845b83811015612fab57815185529382019390820190600101612f8f565b50929695505050505050565b601f821115610ac757600081815260208120601f850160051c81016020861015612fde5750805b601f850160051c820191505b81811015612ffd57828155600101612fea565b505050505050565b815167ffffffffffffffff81111561301f5761301f61239a565b6130338161302d8454612d67565b84612fb7565b602080601f83116001811461306857600084156130505750858301515b600019600386901b1c1916600185901b178555612ffd565b600085815260208120601f198616915b8281101561309757888601518255948401946001909101908401613078565b50858210156130b55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761052857610528612960565b8082018082111561052857610528612960565b6000816130fe576130fe612960565b50600019019056fea26469706673582212204b25d1ae170b1e30763904b55d0c5b86cd5d61f973d1e6fe239cf36daf98e1cc64736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101b95760003560e01c80638456cb59116100f9578063d547741f11610097578063dbd8483d11610071578063dbd8483d146103fb578063de743a7214610420578063e63ab1e914610447578063f76fc35e1461046e57600080fd5b8063d547741f146103c3578063d5f2077c146103d6578063da742228146103e857600080fd5b80639e7495aa116100d35780639e7495aa1461037e578063a217fddf14610391578063c91f0c5314610399578063ce1b815f146103ac57600080fd5b80638456cb591461032257806384b0196e1461032a57806391d148541461034557600080fd5b806336568abe1161016657806359c191e41161014057806359c191e4146102b85780635c975abb146102de57806374e3447a146102e95780637caa719a1461031057600080fd5b806336568abe1461028a5780633f4ba83a1461029d578063572b6c05146102a557600080fd5b80632d94a9d3116101975780632d94a9d31461022c5780632f2ff15d1461023f57806334dcdd521461025257600080fd5b806301ffc9a7146101be5780631a3101b1146101e6578063248a9ca3146101fb575b600080fd5b6101d16101cc366004612358565b610495565b60405190151581526020015b60405180910390f35b6101f96101f43660046124d5565b61052e565b005b61021e61020936600461257f565b600090815260ca602052604090206001015490565b6040519081526020016101dd565b6101f961023a366004612598565b610821565b6101f961024d36600461261d565b610aa2565b610277610260366004612649565b6101316020526000908152604090205461ffff1681565b60405161ffff90911681526020016101dd565b6101f961029836600461261d565b610acc565b6101f9610b68565b6101d16102b3366004612649565b610b9d565b61012e546001600160a01b03165b6040516001600160a01b0390911681526020016101dd565b60fc5460ff166101d1565b61021e7fb696df569c2dfecb5a24edfd39d7f55b0f442be14350cbc68dbe8eb35489d3a681565b61012f546001600160a01b03166102c6565b6101f9610bba565b610332610bec565b6040516101dd97969594939291906126ef565b6101d161035336600461261d565b600091825260ca602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6101f961038c3660046127be565b610cae565b61021e600081565b6101f96103a73660046128b7565b61120c565b6000546201000090046001600160a01b03166102c6565b6101f96103d136600461261d565b6113b1565b610130546001600160a01b03166102c6565b6101f96103f6366004612649565b6113d6565b610277610409366004612649565b6101326020526000908152604090205461ffff1681565b61021e7f52955c021a90f71f7afee289089576ce6998f456ca81e444651c71363bf2609581565b61021e7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b61021e7f3b0c69bab62d38b5774be9b5185349bf525ef97a4d288b652e29bb4ec2a4902d81565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061052857507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b610536611440565b610130546001600160a01b0316636b406341886105a984610132600061055a611495565b6001600160a01b0316815260208101919091526040016000908120805461ffff169161058583612976565b91906101000a81548161ffff021916908361ffff1602179055508b8b8b8b8b6114a4565b6040518363ffffffff1660e01b81526004016105c6929190612997565b602060405180830381865afa1580156105e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060791906129b9565b6106585760405162461bcd60e51b815260206004820152601e60248201527f41737365744372656174653a20496e76616c6964207369676e6174757265000060448201526064015b60405180910390fd5b6001600160a01b03811660009081526101316020526040812080546106bd9184918a9190859061068b9061ffff16612976565b91906101000a81548161ffff021916908361ffff1602179055886106b05760006106b3565b60015b60ff166000611568565b61012f546040517f124d91e50000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260ff8b166024830152604482018a905292935091169063124d91e590606401600060405180830381600087803b15801561073057600080fd5b505af1158015610744573d6000803e3d6000fd5b505061012e546040517fbb7fde710000000000000000000000000000000000000000000000000000000081526001600160a01b03909116925063bb7fde71915061079a90859085908b908a908a90600401612a01565b600060405180830381600087803b1580156107b457600080fd5b505af11580156107c8573d6000803e3d6000fd5b50505050816001600160a01b03167f293c16277edbc93bfb30f56ac279e45bbdbd421755b0278d19ebcd1cee6a795b82898988888b60405161080f96959493929190612a3b565b60405180910390a25050505050505050565b7fb696df569c2dfecb5a24edfd39d7f55b0f442be14350cbc68dbe8eb35489d3a661084b816115b5565b610853611440565b610130546001600160a01b0316636b406341876108c8856101326000610877611495565b6001600160a01b0316815260208101919091526040016000908120805461ffff16916108a283612976565b91906101000a81548161ffff021916908361ffff16021790555060008b60018c8c6114a4565b6040518363ffffffff1660e01b81526004016108e5929190612997565b602060405180830381865afa158015610902573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092691906129b9565b6109725760405162461bcd60e51b815260206004820152601e60248201527f41737365744372656174653a20496e76616c6964207369676e61747572650000604482015260640161064f565b6001600160a01b03821660009081526101316020526040812080546109c791859184919082906109a59061ffff16612976565b91906101000a81548161ffff021916908361ffff160217905560016000611568565b61012e546040517fbb7fde710000000000000000000000000000000000000000000000000000000081529192506001600160a01b03169063bb7fde7190610a1a90869085908b908b908b90600401612a01565b600060405180830381600087803b158015610a3457600080fd5b505af1158015610a48573d6000803e3d6000fd5b50505050826001600160a01b03167f07560e268a00bce229c6a07c00d3f177f67674deae28b79a1840dd20712366288260008989896001604051610a9196959493929190612a79565b60405180910390a250505050505050565b600082815260ca6020526040902060010154610abd816115b5565b610ac783836115c6565b505050565b610ad4611495565b6001600160a01b0316816001600160a01b031614610b5a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161064f565b610b648282611669565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b92816115b5565b610b9a61170a565b50565b600080546001600160a01b03838116620100009092041614610528565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610be4816115b5565b610b9a611762565b6000606080600080600060606032546000801b148015610c0c5750603354155b610c585760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a65640000000000000000000000604482015260640161064f565b610c606117a0565b610c68611832565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b610cb6611440565b610130546001600160a01b0316636b4063418b610d2c846101326000610cda611495565b6001600160a01b0316815260208101919091526040016000908120805461ffff1691610d0583612976565b91906101000a81548161ffff021916908361ffff1602179055508e8e8e8e8e8e8e8e611841565b6040518363ffffffff1660e01b8152600401610d49929190612997565b602060405180830381865afa158015610d66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8a91906129b9565b610dd65760405162461bcd60e51b815260206004820152601e60248201527f41737365744372656174653a20496e76616c6964207369676e61747572650000604482015260640161064f565b878614610e355760405162461bcd60e51b815260206004820152602760248201527f41737365744372656174653a20417272617973206d7573742062652073616d65604482015266040d8cadccee8d60cb1b606482015260840161064f565b858214610e945760405162461bcd60e51b815260206004820152602760248201527f41737365744372656174653a20417272617973206d7573742062652073616d65604482015266040d8cadccee8d60cb1b606482015260840161064f565b818414610ef35760405162461bcd60e51b815260206004820152602760248201527f41737365744372656174653a20417272617973206d7573742062652073616d65604482015266040d8cadccee8d60cb1b606482015260840161064f565b60008867ffffffffffffffff811115610f0e57610f0e61239a565b604051908082528060200260200182016040528015610f37578160200160208202803683370190505b50905060008967ffffffffffffffff811115610f5557610f5561239a565b604051908082528060200260200182016040528015610f7e578160200160208202803683370190505b50905060005b8a8110156110a4578b8b82818110610f9e57610f9e612aa3565b9050602002016020810190610fb39190612ab9565b60ff16828281518110610fc857610fc8612aa3565b602002602001018181525050611075848d8d84818110610fea57610fea612aa3565b9050602002016020810190610fff9190612ab9565b6001600160a01b038716600090815261013160205260408120805490919061102a9061ffff16612976565b91906101000a81548161ffff021916908361ffff16021790558b8b8681811061105557611055612aa3565b905060200201602081019061106a9190612ad4565b6106b05760006106b3565b83828151811061108757611087612aa3565b60209081029190910101528061109c81612af1565b915050610f84565b5061012f546040517f20820ec30000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906320820ec3906110f590869085908e908e90600401612b56565b600060405180830381600087803b15801561110f57600080fd5b505af1158015611123573d6000803e3d6000fd5b505061012e546040517fa55784ef0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116925063a55784ef915061117b90869086908e908e908c908c90600401612c3b565b600060405180830381600087803b15801561119557600080fd5b505af11580156111a9573d6000803e3d6000fd5b50505050826001600160a01b03167fdd4b554190cbd4759e711abb655bdaf12557fea0ac84cec4fd4d978db3148bab838d8d8d8d8b8b8f8f6040516111f699989796959493929190612c92565b60405180910390a2505050505050505050505050565b600054610100900460ff161580801561122c5750600054600160ff909116105b806112465750303b158015611246575060005460ff166001145b6112b85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161064f565b6000805460ff1916600117905580156112db576000805461ff0019166101001790555b61012e80546001600160a01b038089167fffffffffffffffffffffffff00000000000000000000000000000000000000009283161790925561012f805488841690831617905561013080549287169290911691909117905561133c83611950565b61134688886119c4565b61134e611a39565b611356611aa4565b6113616000836115c6565b80156113a7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b600082815260ca60205260409020600101546113cc816115b5565b610ac78383611669565b60006113e1816115b5565b6001600160a01b0382166114375760405162461bcd60e51b815260206004820152601960248201527f41737365744372656174653a205a65726f206164647265737300000000000000604482015260640161064f565b610b6482611b17565b60fc5460ff16156114935760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161064f565b565b600061149f611c2c565b905090565b600061155c7f3b0c69bab62d38b5774be9b5185349bf525ef97a4d288b652e29bb4ec2a4902d898989898989896040516020016114e2929190612d57565b60408051601f198184030181528282528051602091820120908301989098526001600160a01b039096169581019590955261ffff909316606085015260ff909116608084015260a0830152151560c082015260e0810191909152610100015b60405160208183030381529060405280519060200120611c36565b98975050505050505050565b60008560c88361157957600061157c565b60015b60ff16901b60b88561ffff16901b60a88761ffff16901b60a08960ff16901b846001600160a01b03161717171791505095945050505050565b610b9a816115c1611495565b611c7e565b600082815260ca602090815260408083206001600160a01b038516845290915290205460ff16610b6457600082815260ca602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611625611495565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260ca602090815260408083206001600160a01b038516845290915290205460ff1615610b6457600082815260ca602090815260408083206001600160a01b03851684529091529020805460ff191690556116c6611495565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b611712611cf3565b60fc805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611745611495565b6040516001600160a01b03909116815260200160405180910390a1565b61176a611440565b60fc805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611745611495565b6060603480546117af90612d67565b80601f01602080910402602001604051908101604052809291908181526020018280546117db90612d67565b80156118285780601f106117fd57610100808354040283529160200191611828565b820191906000526020600020905b81548152906001019060200180831161180b57829003601f168201915b5050505050905090565b6060603580546117af90612d67565b60006119417f52955c021a90f71f7afee289089576ce6998f456ca81e444651c71363bf260958c8c8c8c60405160200161187c929190612da1565b604051602081830303815290604052805190602001208b8b6040516020016118a5929190612ddb565b604051602081830303815290604052805190602001208a8a6040516020016118ce929190612e1d565b60408051601f1981840301815291905280516020909101206118f86118f38a8c612e4d565b611d45565b6040805160208101989098526001600160a01b039096169587019590955261ffff9093166060860152608085019190915260a084015260c083015260e082015261010001611541565b9b9a5050505050505050505050565b600054610100900460ff166119bb5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b610b9a81611e39565b600054610100900460ff16611a2f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b610b648282611ead565b600054610100900460ff166114935760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b600054610100900460ff16611b0f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b611493611f40565b6000546001600160a01b0362010000909104811690821603611ba15760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c72656164792073657400000000000000000000000000000000606482015260840161064f565b611ba9611495565b600080546040516001600160a01b0393841693858116936201000090930416917f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e591a4600080546001600160a01b0390921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b600061149f611fb7565b6000610528611c4361200e565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b600082815260ca602090815260408083206001600160a01b038516845290915290205460ff16610b6457611cb181612018565b611cbc83602061202a565b604051602001611ccd929190612ed1565b60408051601f198184030181529082905262461bcd60e51b825261064f91600401612f52565b60fc5460ff166114935760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161064f565b600080825167ffffffffffffffff811115611d6257611d6261239a565b604051908082528060200260200182016040528015611d8b578160200160208202803683370190505b50905060005b8351811015611e0957838181518110611dac57611dac612aa3565b6020026020010151604051602001611dc49190612f65565b60405160208183030381529060405280519060200120828281518110611dec57611dec612aa3565b602090810291909101015280611e0181612af1565b915050611d91565b5080604051602001611e1b9190612f81565b60405160208183030381529060405280519060200120915050919050565b600054610100900460ff16611ea45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b610b9a81611b17565b600054610100900460ff16611f185760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b6034611f248382613005565b506035611f318282613005565b50506000603281905560335550565b600054610100900460ff16611fab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161064f565b60fc805460ff19169055565b600080546201000090046001600160a01b031633148015611fd9575060143610155b1561200957507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600061149f61225a565b60606105286001600160a01b03831660145b606060006120398360026130c5565b6120449060026130dc565b67ffffffffffffffff81111561205c5761205c61239a565b6040519080825280601f01601f191660200182016040528015612086576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106120bd576120bd612aa3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061212057612120612aa3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061215c8460026130c5565b6121679060016130dc565b90505b6001811115612204577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106121a8576121a8612aa3565b1a60f81b8282815181106121be576121be612aa3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936121fd816130ef565b905061216a565b5083156122535760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161064f565b9392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6122856122ce565b61228d612327565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6000806122d96117a0565b8051909150156122f0578051602090910120919050565b60325480156122ff5792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b600080612332611832565b805190915015612349578051602090910120919050565b60335480156122ff5792915050565b60006020828403121561236a57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461225357600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156123d9576123d961239a565b604052919050565b600082601f8301126123f257600080fd5b813567ffffffffffffffff81111561240c5761240c61239a565b61241f6020601f19601f840116016123b0565b81815284602083860101111561243457600080fd5b816020850160208301376000918101602001919091529392505050565b803560ff8116811461246257600080fd5b919050565b8015158114610b9a57600080fd5b60008083601f84011261248757600080fd5b50813567ffffffffffffffff81111561249f57600080fd5b6020830191508360208285010111156124b757600080fd5b9250929050565b80356001600160a01b038116811461246257600080fd5b600080600080600080600060c0888a0312156124f057600080fd5b873567ffffffffffffffff8082111561250857600080fd5b6125148b838c016123e1565b985061252260208b01612451565b975060408a0135965060608a0135915061253b82612467565b9094506080890135908082111561255157600080fd5b5061255e8a828b01612475565b9094509250612571905060a089016124be565b905092959891949750929550565b60006020828403121561259157600080fd5b5035919050565b6000806000806000608086880312156125b057600080fd5b853567ffffffffffffffff808211156125c857600080fd5b6125d489838a016123e1565b96506020880135955060408801359150808211156125f157600080fd5b506125fe88828901612475565b90945092506126119050606087016124be565b90509295509295909350565b6000806040838503121561263057600080fd5b82359150612640602084016124be565b90509250929050565b60006020828403121561265b57600080fd5b612253826124be565b60005b8381101561267f578181015183820152602001612667565b50506000910152565b600081518084526126a0816020860160208601612664565b601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b838110156126e4578151875295820195908201906001016126c8565b509495945050505050565b7fff000000000000000000000000000000000000000000000000000000000000008816815260e06020820152600061272a60e0830189612688565b828103604084015261273c8189612688565b90508660608401526001600160a01b03861660808401528460a084015282810360c084015261276b81856126b4565b9a9950505050505050505050565b60008083601f84011261278b57600080fd5b50813567ffffffffffffffff8111156127a357600080fd5b6020830191508360208260051b85010111156124b757600080fd5b60008060008060008060008060008060c08b8d0312156127dd57600080fd5b8a3567ffffffffffffffff808211156127f557600080fd5b6128018e838f016123e1565b9b5060208d013591508082111561281757600080fd5b6128238e838f01612779565b909b50995060408d013591508082111561283c57600080fd5b6128488e838f01612779565b909950975060608d013591508082111561286157600080fd5b61286d8e838f01612779565b909750955060808d013591508082111561288657600080fd5b506128938d828e01612779565b90945092506128a6905060a08c016124be565b90509295989b9194979a5092959850565b600080600080600080600060e0888a0312156128d257600080fd5b873567ffffffffffffffff808211156128ea57600080fd5b6128f68b838c016123e1565b985060208a013591508082111561290c57600080fd5b506129198a828b016123e1565b965050612928604089016124be565b9450612936606089016124be565b9350612944608089016124be565b925061295260a089016124be565b915061257160c089016124be565b634e487b7160e01b600052601160045260246000fd5b600061ffff80831681810361298d5761298d612960565b6001019392505050565b6040815260006129aa6040830185612688565b90508260208301529392505050565b6000602082840312156129cb57600080fd5b815161225381612467565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b6001600160a01b0386168152846020820152836040820152608060608201526000612a306080830184866129d6565b979650505050505050565b86815260ff8616602082015284604082015260a060608201526000612a6460a0830185876129d6565b90508215156080830152979650505050505050565b86815261ffff8616602082015284604082015260a060608201526000612a6460a0830185876129d6565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612acb57600080fd5b61225382612451565b600060208284031215612ae657600080fd5b813561225381612467565b60006000198203612b0457612b04612960565b5060010190565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612b3d57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0385168152606060208201526000612b7860608301866126b4565b8281036040840152612a30818587612b0b565b81835260006020808501808196508560051b810191508460005b87811015612c2e57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1883603018112612be457600080fd5b8701858101903567ffffffffffffffff811115612c0057600080fd5b803603821315612c0f57600080fd5b612c1a8682846129d6565b9a87019a9550505090840190600101612ba5565b5091979650505050505050565b6001600160a01b0387168152608060208201526000612c5d60808301886126b4565b8281036040840152612c70818789612b0b565b90508281036060840152612c85818587612b8b565b9998505050505050505050565b60a081526000612ca560a083018c6126b4565b8281036020848101919091528a82528b91810160005b8c811015612ce15760ff612cce85612451565b1682529282019290820190600101612cbb565b508481036040860152612cf5818b8d612b0b565b9250508382036060850152612d0b82888a612b8b565b8481036080860152858152869250810160005b86811015612d45578335612d3181612467565b151582529282019290820190600101612d1e565b509d9c50505050505050505050505050565b8183823760009101908152919050565b600181811c90821680612d7b57607f821691505b602082108103612d9b57634e487b7160e01b600052602260045260246000fd5b50919050565b60008184825b85811015612dd05760ff612dba83612451565b1683526020928301929190910190600101612da7565b509095945050505050565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612e0a57600080fd5b8260051b80858437919091019392505050565b60008184825b85811015612dd0578135612e3681612467565b151583526020928301929190910190600101612e23565b600067ffffffffffffffff80841115612e6857612e6861239a565b8360051b6020612e798183016123b0565b868152918501918181019036841115612e9157600080fd5b865b84811015612ec557803586811115612eab5760008081fd5b612eb736828b016123e1565b845250918301918301612e93565b50979650505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612f09816017850160208801612664565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351612f46816028840160208801612664565b01602801949350505050565b6020815260006122536020830184612688565b60008251612f77818460208701612664565b9190910192915050565b815160009082906020808601845b83811015612fab57815185529382019390820190600101612f8f565b50929695505050505050565b601f821115610ac757600081815260208120601f850160051c81016020861015612fde5750805b601f850160051c820191505b81811015612ffd57828155600101612fea565b505050505050565b815167ffffffffffffffff81111561301f5761301f61239a565b6130338161302d8454612d67565b84612fb7565b602080601f83116001811461306857600084156130505750858301515b600019600386901b1c1916600185901b178555612ffd565b600085815260208120601f198616915b8281101561309757888601518255948401946001909101908401613078565b50858210156130b55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761052857610528612960565b8082018082111561052857610528612960565b6000816130fe576130fe612960565b50600019019056fea26469706673582212204b25d1ae170b1e30763904b55d0c5b86cd5d61f973d1e6fe239cf36daf98e1cc64736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "events": { + "EIP712DomainChanged()": { + "details": "MAY be emitted to signal that the domain could have changed." + }, + "Initialized(uint8)": { + "details": "Triggered when the contract has been initialized or reinitialized." + }, + "Paused(address)": { + "details": "Emitted when the pause is triggered by `account`." + }, + "RoleAdminChanged(bytes32,bytes32,bytes32)": { + "details": "Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._" + }, + "RoleGranted(bytes32,address,address)": { + "details": "Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}." + }, + "RoleRevoked(bytes32,address,address)": { + "details": "Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)" + }, + "TrustedForwarderSet(address,address,address)": { + "params": { + "newTrustedForwarder": "new trusted forwarder", + "oldTrustedForwarder": "old trusted forwarder", + "operator": "the sender of the transaction" + } + }, + "Unpaused(address)": { + "details": "Emitted when the pause is lifted by `account`." + } + }, + "kind": "dev", + "methods": { + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "createAsset(bytes,uint8,uint256,bool,string,address)": { + "params": { + "amount": "The amount of the asset to mint", + "creator": "The address of the creator", + "metadataHash": "The metadata hash of the asset to mint", + "revealed": "Whether the asset is revealed or not", + "signature": "A signature generated by TSB", + "tier": "The tier of the asset to mint" + } + }, + "createMultipleAssets(bytes,uint8[],uint256[],bool[],string[],address)": { + "params": { + "amounts": "The amounts of the assets to mint", + "creator": "The address of the creator", + "metadataHashes": "The metadata hashes of the assets to mint", + "revealed": "Whether the assets are revealed or not", + "signature": "A signature generated by TSB", + "tiers": "The tiers of the assets to mint" + } + }, + "createSpecialAsset(bytes,uint256,string,address)": { + "details": "Only callable by the special minter", + "params": { + "amount": "The amount of the asset to mint", + "creator": "The address of the creator", + "metadataHash": "The metadata hash of the asset to mint,", + "signature": "A signature generated by TSB" + } + }, + "eip712Domain()": { + "details": "See {EIP-5267}. _Available since v4.9._" + }, + "getAssetContract()": { + "returns": { + "assetContractAddress": "The asset contract address" + } + }, + "getAuthValidator()": { + "returns": { + "authValidatorAddress": "The auth validator address" + } + }, + "getCatalystContract()": { + "returns": { + "catalystContractAddress": "The catalyst contract address" + } + }, + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getTrustedForwarder()": { + "returns": { + "_0": "return the address of the trusted forwarder" + } + }, + "grantRole(bytes32,address)": { + "details": "Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event." + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "initialize(string,string,address,address,address,address,address)": { + "params": { + "_assetContract": "The address of the asset contract", + "_authValidator": "The address of the AuthSuperValidator contract", + "_catalystContract": "The address of the catalyst contract", + "_defaultAdmin": "The address of the default admin", + "_forwarder": "The address of the forwarder contract", + "_name": "The name of the contract (for EIP712)", + "_version": "The version of the contract (for EIP712)" + } + }, + "isTrustedForwarder(address)": { + "params": { + "forwarder": "trusted forwarder address to check" + }, + "returns": { + "_0": "true if the address is the same as the trusted forwarder" + } + }, + "paused()": { + "details": "Returns true if the contract is paused, and false otherwise." + }, + "renounceRole(bytes32,address)": { + "details": "Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event." + }, + "revokeRole(bytes32,address)": { + "details": "Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event." + }, + "setTrustedForwarder(address)": { + "details": "Change the address of the trusted forwarder for meta-TX", + "params": { + "trustedForwarder": "The new trustedForwarder" + } + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + } + }, + "title": "AssetCreate", + "version": 1 + }, + "userdoc": { + "events": { + "TrustedForwarderSet(address,address,address)": { + "notice": "Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`" + } + }, + "kind": "user", + "methods": { + "createAsset(bytes,uint8,uint256,bool,string,address)": { + "notice": "Create a new asset" + }, + "createMultipleAssets(bytes,uint8[],uint256[],bool[],string[],address)": { + "notice": "Create multiple assets at once" + }, + "createSpecialAsset(bytes,uint256,string,address)": { + "notice": "Create special assets, like TSB exclusive tokens" + }, + "getAssetContract()": { + "notice": "Get the asset contract address" + }, + "getAuthValidator()": { + "notice": "Get the auth validator address" + }, + "getCatalystContract()": { + "notice": "Get the catalyst contract address" + }, + "getTrustedForwarder()": { + "notice": "return the address of the trusted forwarder" + }, + "initialize(string,string,address,address,address,address,address)": { + "notice": "Initialize the contract" + }, + "isTrustedForwarder(address)": { + "notice": "return true if the forwarder is the trusted forwarder" + }, + "pause()": { + "notice": "Pause the contracts mint and burn functions" + }, + "setTrustedForwarder(address)": { + "notice": "Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only" + }, + "unpause()": { + "notice": "Unpause the contracts mint and burn functions" + } + }, + "notice": "User-facing contract for creating new assets", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 502, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 505, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 11744, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_trustedForwarder", + "offset": 2, + "slot": "0", + "type": "t_address" + }, + { + "astId": 11855, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 3579, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_hashedName", + "offset": 0, + "slot": "50", + "type": "t_bytes32" + }, + { + "astId": 3582, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_hashedVersion", + "offset": 0, + "slot": "51", + "type": "t_bytes32" + }, + { + "astId": 3584, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_name", + "offset": 0, + "slot": "52", + "type": "t_string_storage" + }, + { + "astId": 3586, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_version", + "offset": 0, + "slot": "53", + "type": "t_string_storage" + }, + { + "astId": 3844, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "__gap", + "offset": 0, + "slot": "54", + "type": "t_array(t_uint256)48_storage" + }, + { + "astId": 2965, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 3888, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 82, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_roles", + "offset": 0, + "slot": "202", + "type": "t_mapping(t_bytes32,t_struct(RoleData)77_storage)" + }, + { + "astId": 377, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "__gap", + "offset": 0, + "slot": "203", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 685, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "_paused", + "offset": 0, + "slot": "252", + "type": "t_bool" + }, + { + "astId": 790, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "__gap", + "offset": 0, + "slot": "253", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 7696, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "assetContract", + "offset": 0, + "slot": "302", + "type": "t_contract(IAsset)10610" + }, + { + "astId": 7699, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "catalystContract", + "offset": 0, + "slot": "303", + "type": "t_contract(ICatalyst)10822" + }, + { + "astId": 7702, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "authValidator", + "offset": 0, + "slot": "304", + "type": "t_contract(AuthSuperValidator)9788" + }, + { + "astId": 7706, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "creatorNonces", + "offset": 0, + "slot": "305", + "type": "t_mapping(t_address,t_uint16)" + }, + { + "astId": 7710, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "signatureNonces", + "offset": 0, + "slot": "306", + "type": "t_mapping(t_address,t_uint16)" + }, + { + "astId": 8380, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "__gap", + "offset": 0, + "slot": "307", + "type": "t_array(t_uint256)45_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)45_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "t_array(t_uint256)48_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[48]", + "numberOfBytes": "1536" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(AuthSuperValidator)9788": { + "encoding": "inplace", + "label": "contract AuthSuperValidator", + "numberOfBytes": "20" + }, + "t_contract(IAsset)10610": { + "encoding": "inplace", + "label": "contract IAsset", + "numberOfBytes": "20" + }, + "t_contract(ICatalyst)10822": { + "encoding": "inplace", + "label": "contract ICatalyst", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_uint16)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint16)", + "numberOfBytes": "32", + "value": "t_uint16" + }, + "t_mapping(t_bytes32,t_struct(RoleData)77_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)77_storage" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(RoleData)77_storage": { + "encoding": "inplace", + "label": "struct AccessControlUpgradeable.RoleData", + "members": [ + { + "astId": 74, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 76, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol:AssetCreate", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_uint16": { + "encoding": "inplace", + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/AssetCreate_Proxy.json b/packages/deploy/deployments/mumbai/AssetCreate_Proxy.json new file mode 100644 index 0000000000..fc1c81e8c5 --- /dev/null +++ b/packages/deploy/deployments/mumbai/AssetCreate_Proxy.json @@ -0,0 +1,292 @@ +{ + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "transactionIndex": 31, + "gasUsed": "898346", + "logsBloom": "0x00000004000000000000000000000000480000000000000000000080000000000002000000009400000000000001080000008000000000000000000000000000000000000000000000000000000002800000000000000000000100000000004000000000020000000000020000000800000000800000000080000000000000000000010040000000000000000000000000000000000080000000000000a0000020000000000000000000000000040000000000000000000000500000000400400000002000000000000100000004000000000000040000010010c040000020002000000000000000000000000000000004000000000000000000000000100000", + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9", + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "logs": [ + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000ed8bdb8d96d15b59d37231c520aa508c4b8b986a" + ], + "data": "0x", + "logIndex": 137, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 138, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 139, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 140, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0xfc5d0eA2074ABDeb94ab49d09b66b8f35E594cEc", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 141, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + }, + { + "transactionIndex": 31, + "blockNumber": 40238289, + "transactionHash": "0x68c35b3151cc857bf9ac382d5f8d55bb5b61296494fc1a8d0e60120cd57568ed", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000072e579213093600000000000000000000000000000000000000000000000fbfa9fd925ed44859000000000000000000000000000000000000000000003472aecd38c6bb3ddbe800000000000000000000000000000000000000000000000fbfa2cf3accc13f23000000000000000000000000000000000000000000003472aed4671e4d50e51e", + "logIndex": 142, + "blockHash": "0x5fedabd3a69c4e2c7fa906280e3538863c5aa51a32b5c9759d9c56b884b53ec9" + } + ], + "blockNumber": 40238289, + "cumulativeGasUsed": "6946356", + "status": 1, + "byzantium": true + }, + "args": [ + "0xED8Bdb8D96d15B59d37231C520aa508C4B8B986a", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xc91f0c5300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000178fd5dec6477364d1beba000e07c18b7be61645000000000000000000000000059c6c226ec83742932b259153f63e333b767a5000000000000000000000000012467f6e7b23347abe0109968a9886a6c408d25a00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f700000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165000000000000000000000000000000000000000000000000000000000000001453616e64626f78204173736574204372656174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000003312e300000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/AssetReveal.json b/packages/deploy/deployments/mumbai/AssetReveal.json new file mode 100644 index 0000000000..58e242f5b7 --- /dev/null +++ b/packages/deploy/deployments/mumbai/AssetReveal.json @@ -0,0 +1,1142 @@ +{ + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "revealer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "unrevealedTokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "AssetRevealBatchBurn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "unrevealedTokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[][]", + "name": "amounts", + "type": "uint256[][]" + }, + { + "indexed": false, + "internalType": "uint256[][]", + "name": "newTokenIds", + "type": "uint256[][]" + }, + { + "indexed": false, + "internalType": "bytes32[][]", + "name": "revealHashes", + "type": "bytes32[][]" + } + ], + "name": "AssetRevealBatchMint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "revealer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unrevealedTokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetRevealBurn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unrevealedTokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "newTokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "revealHashes", + "type": "bytes32[]" + } + ], + "name": "AssetRevealMint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "BATCH_REVEAL_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INSTANT_REVEAL_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REVEAL_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "prevTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "burnAmount", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "internalType": "bytes32[]", + "name": "revealHashes", + "type": "bytes32[]" + } + ], + "name": "burnAndReveal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAssetContract", + "outputs": [ + { + "internalType": "address", + "name": "assetContractAddres", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthValidator", + "outputs": [ + { + "internalType": "address", + "name": "authValidatorContractAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + } + ], + "name": "getTierInstantRevealAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "instantRevealAllowed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_version", + "type": "string" + }, + { + "internalType": "address", + "name": "_assetContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_authValidator", + "type": "address" + }, + { + "internalType": "address", + "name": "_forwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultAdmin", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "revealBatchBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256[]", + "name": "prevTokenIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[][]", + "name": "amounts", + "type": "uint256[][]" + }, + { + "internalType": "string[][]", + "name": "metadataHashes", + "type": "string[][]" + }, + { + "internalType": "bytes32[][]", + "name": "revealHashes", + "type": "bytes32[][]" + } + ], + "name": "revealBatchMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "revealBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "revealHash", + "type": "bytes32" + } + ], + "name": "revealHashUsed", + "outputs": [ + { + "internalType": "bool", + "name": "hashUsed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "prevTokenId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "internalType": "bytes32[]", + "name": "revealHashes", + "type": "bytes32[]" + } + ], + "name": "revealMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + } + ], + "name": "setTierInstantRevealAllowed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "transactionIndex": 1, + "gasUsed": "897468", + "logsBloom": "0x00000084000000000000000000000000400000000000000000000080000000000002000000008400000000000001000000008000000000000000000000000000000000000000000000000000000002800000000000000000000100000000004000000000020000000020020000000800000000800000000080000000000000000000010040000020000000000000000000000000000080000000000000a00000200000000000000000000000001400000000000000000000001000000000004000000020000000000001000000040000000000000420000100108040000020002000000000000000000000000000000004000000000000000000000000100200", + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b", + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000006a2b6427d56495a0e49fc4d1c3bb3ac32c2d5e0d" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 6, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 7, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 8, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 9, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x0000000000000000000000000000000000000000000000000007f89b2157dc0000000000000000000000000000000000000000000000000fbf907844003fb6e4000000000000000000000000000000000000000000003472b012f4a25ee5a15900000000000000000000000000000000000000000000000fbf887fa8dee7dae4000000000000000000000000000000000000000000003472b01aed3d803d7d59", + "logIndex": 10, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + } + ], + "blockNumber": 40238295, + "cumulativeGasUsed": "1118752", + "status": 1, + "byzantium": true + }, + "args": [ + "0x6a2B6427d56495A0e49Fc4D1C3Bb3ac32C2d5E0D", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xe56f2fe400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000178fd5dec6477364d1beba000e07c18b7be6164500000000000000000000000012467f6e7b23347abe0109968a9886a6c408d25a00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f700000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165000000000000000000000000000000000000000000000000000000000000001453616e64626f782041737365742052657665616c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000003312e300000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "Sandbox Asset Reveal", + "1.0", + "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "0x12467f6e7b23347ABE0109968A9886A6c408d25a", + "0x69015912aa33720b842dcd6ac059ed623f28d9f7", + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165" + ] + }, + "implementation": "0x6a2B6427d56495A0e49Fc4D1C3Bb3ac32C2d5E0D", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/AssetReveal_Implementation.json b/packages/deploy/deployments/mumbai/AssetReveal_Implementation.json new file mode 100644 index 0000000000..5449f1bbc0 --- /dev/null +++ b/packages/deploy/deployments/mumbai/AssetReveal_Implementation.json @@ -0,0 +1,1417 @@ +{ + "address": "0x6a2B6427d56495A0e49Fc4D1C3Bb3ac32C2d5E0D", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "revealer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "unrevealedTokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "AssetRevealBatchBurn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "unrevealedTokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[][]", + "name": "amounts", + "type": "uint256[][]" + }, + { + "indexed": false, + "internalType": "uint256[][]", + "name": "newTokenIds", + "type": "uint256[][]" + }, + { + "indexed": false, + "internalType": "bytes32[][]", + "name": "revealHashes", + "type": "bytes32[][]" + } + ], + "name": "AssetRevealBatchMint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "revealer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unrevealedTokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "AssetRevealBurn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unrevealedTokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "newTokenIds", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "revealHashes", + "type": "bytes32[]" + } + ], + "name": "AssetRevealMint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "BATCH_REVEAL_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INSTANT_REVEAL_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REVEAL_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "prevTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "burnAmount", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "internalType": "bytes32[]", + "name": "revealHashes", + "type": "bytes32[]" + } + ], + "name": "burnAndReveal", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAssetContract", + "outputs": [ + { + "internalType": "address", + "name": "assetContractAddres", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthValidator", + "outputs": [ + { + "internalType": "address", + "name": "authValidatorContractAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + } + ], + "name": "getTierInstantRevealAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "instantRevealAllowed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_version", + "type": "string" + }, + { + "internalType": "address", + "name": "_assetContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_authValidator", + "type": "address" + }, + { + "internalType": "address", + "name": "_forwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultAdmin", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "tokenIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "revealBatchBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256[]", + "name": "prevTokenIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[][]", + "name": "amounts", + "type": "uint256[][]" + }, + { + "internalType": "string[][]", + "name": "metadataHashes", + "type": "string[][]" + }, + { + "internalType": "bytes32[][]", + "name": "revealHashes", + "type": "bytes32[][]" + } + ], + "name": "revealBatchMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "revealBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "revealHash", + "type": "bytes32" + } + ], + "name": "revealHashUsed", + "outputs": [ + { + "internalType": "bool", + "name": "hashUsed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "prevTokenId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + }, + { + "internalType": "bytes32[]", + "name": "revealHashes", + "type": "bytes32[]" + } + ], + "name": "revealMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + } + ], + "name": "setTierInstantRevealAllowed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x93abf27163fceed67d970662180ea5a5e4c362a1f3698ac917ae2d92f1eda635", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x6a2B6427d56495A0e49Fc4D1C3Bb3ac32C2d5E0D", + "transactionIndex": 9, + "gasUsed": "3441445", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000200000000002100000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000200000200000000000000000000000000400000000000000000000000000800000004000000000000000000001000000040000000000000000000000108040000000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x927e02e5a3f3b7afc731906938b97ccae3f6c4f0779baa9ba26639dfa0481f25", + "transactionHash": "0x93abf27163fceed67d970662180ea5a5e4c362a1f3698ac917ae2d92f1eda635", + "logs": [ + { + "transactionIndex": 9, + "blockNumber": 40238292, + "transactionHash": "0x93abf27163fceed67d970662180ea5a5e4c362a1f3698ac917ae2d92f1eda635", + "address": "0x6a2B6427d56495A0e49Fc4D1C3Bb3ac32C2d5E0D", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 46, + "blockHash": "0x927e02e5a3f3b7afc731906938b97ccae3f6c4f0779baa9ba26639dfa0481f25" + }, + { + "transactionIndex": 9, + "blockNumber": 40238292, + "transactionHash": "0x93abf27163fceed67d970662180ea5a5e4c362a1f3698ac917ae2d92f1eda635", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x000000000000000000000000000000000000000000000000001256f6c81bcb0000000000000000000000000000000000000000000000000fbfa2cf3acbd83759000000000000000000000000000000000000000000003472af734ae0a005cdd500000000000000000000000000000000000000000000000fbf90784403bc6c59000000000000000000000000000000000000000000003472af85a1d7682198d5", + "logIndex": 47, + "blockHash": "0x927e02e5a3f3b7afc731906938b97ccae3f6c4f0779baa9ba26639dfa0481f25" + } + ], + "blockNumber": 40238292, + "cumulativeGasUsed": "5057055", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "a7dad225e4948fd90c6be2fd4b947044", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"revealer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"unrevealedTokenIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"AssetRevealBatchBurn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"unrevealedTokenIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[][]\",\"name\":\"amounts\",\"type\":\"uint256[][]\"},{\"indexed\":false,\"internalType\":\"uint256[][]\",\"name\":\"newTokenIds\",\"type\":\"uint256[][]\"},{\"indexed\":false,\"internalType\":\"bytes32[][]\",\"name\":\"revealHashes\",\"type\":\"bytes32[][]\"}],\"name\":\"AssetRevealBatchMint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"revealer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unrevealedTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AssetRevealBurn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unrevealedTokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"newTokenIds\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"revealHashes\",\"type\":\"bytes32[]\"}],\"name\":\"AssetRevealMint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"EIP712DomainChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarderAddress\",\"type\":\"address\"}],\"name\":\"TrustedForwarderChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"TrustedForwarderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BATCH_REVEAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INSTANT_REVEAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PAUSER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REVEAL_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"prevTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"burnAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"metadataHashes\",\"type\":\"string[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"revealHashes\",\"type\":\"bytes32[]\"}],\"name\":\"burnAndReveal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eip712Domain\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"fields\",\"type\":\"bytes1\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"verifyingContract\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"extensions\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAssetContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"assetContractAddres\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAuthValidator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"authValidatorContractAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"tier\",\"type\":\"uint8\"}],\"name\":\"getTierInstantRevealAllowed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"instantRevealAllowed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTrustedForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_version\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_assetContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_authValidator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultAdmin\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isTrustedForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"tokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"revealBatchBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256[]\",\"name\":\"prevTokenIds\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"amounts\",\"type\":\"uint256[][]\"},{\"internalType\":\"string[][]\",\"name\":\"metadataHashes\",\"type\":\"string[][]\"},{\"internalType\":\"bytes32[][]\",\"name\":\"revealHashes\",\"type\":\"bytes32[][]\"}],\"name\":\"revealBatchMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"revealBurn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"revealHash\",\"type\":\"bytes32\"}],\"name\":\"revealHashUsed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"hashUsed\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"prevTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"metadataHashes\",\"type\":\"string[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"revealHashes\",\"type\":\"bytes32[]\"}],\"name\":\"revealMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"tier\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"}],\"name\":\"setTierInstantRevealAllowed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"trustedForwarder\",\"type\":\"address\"}],\"name\":\"setTrustedForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"events\":{\"EIP712DomainChanged()\":{\"details\":\"MAY be emitted to signal that the domain could have changed.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"RoleAdminChanged(bytes32,bytes32,bytes32)\":{\"details\":\"Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._\"},\"RoleGranted(bytes32,address,address)\":{\"details\":\"Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}.\"},\"RoleRevoked(bytes32,address,address)\":{\"details\":\"Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)\"},\"TrustedForwarderSet(address,address,address)\":{\"params\":{\"newTrustedForwarder\":\"new trusted forwarder\",\"oldTrustedForwarder\":\"old trusted forwarder\",\"operator\":\"the sender of the transaction\"}},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"}},\"kind\":\"dev\",\"methods\":{\"burnAndReveal(bytes,uint256,uint256,uint256[],string[],bytes32[])\":{\"details\":\"Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\",\"params\":{\"amounts\":\"The amount of assets to reveal (sum must be equal to the burnAmount)\",\"burnAmount\":\"The amount of assets to burn\",\"metadataHashes\":\"The array of hashes for asset metadata\",\"prevTokenId\":\"The tokenId of the unrevealed asset\",\"revealHashes\":\"A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\",\"signature\":\"Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"eip712Domain()\":{\"details\":\"See {EIP-5267}. _Available since v4.9._\"},\"getAssetContract()\":{\"returns\":{\"assetContractAddres\":\"The asset contract address\"}},\"getAuthValidator()\":{\"returns\":{\"authValidatorContractAddress\":\"The auth validator address\"}},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getTierInstantRevealAllowed(uint8)\":{\"params\":{\"tier\":\"The tier to check\"},\"returns\":{\"instantRevealAllowed\":\"Boolean representing whether instant reveal is allowed for the given tier\"}},\"getTrustedForwarder()\":{\"returns\":{\"_0\":\"return the address of the trusted forwarder\"}},\"grantRole(bytes32,address)\":{\"details\":\"Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event.\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"initialize(string,string,address,address,address,address)\":{\"params\":{\"_assetContract\":\"The address of the asset contract\",\"_authValidator\":\"The address of the AuthSuperValidator contract\",\"_forwarder\":\"The address of the forwarder contract\"}},\"isTrustedForwarder(address)\":{\"params\":{\"forwarder\":\"trusted forwarder address to check\"},\"returns\":{\"_0\":\"true if the address is the same as the trusted forwarder\"}},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event.\"},\"revealBatchBurn(uint256[],uint256[])\":{\"details\":\"Can be used to burn multiple copies of the same token id, each copy will be revealed separately\",\"params\":{\"amounts\":\"the amounts of the assets to burn\",\"tokenIds\":\"the tokenIds of the assets to burn\"}},\"revealBatchMint(bytes,uint256[],uint256[][],string[][],bytes32[][])\":{\"details\":\"Can be used to reveal multiple copies of the same token id\",\"params\":{\"amounts\":\"The amount of assets to reveal (must be equal to the length of revealHashes)\",\"metadataHashes\":\"The array of hashes for asset metadata\",\"prevTokenIds\":\"The tokenId of the unrevealed asset\",\"revealHashes\":\"Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\",\"signature\":\"Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\"}},\"revealBurn(uint256,uint256)\":{\"details\":\"the reveal mechanism works through burning the asset and minting a new one with updated tokenId\",\"params\":{\"amount\":\"the amount of tokens to reveal\",\"tokenId\":\"the tokenId of id idasset to reveal\"}},\"revealHashUsed(bytes32)\":{\"returns\":{\"hashUsed\":\"Boolean representing whether the hash has been used\"}},\"revealMint(bytes,uint256,uint256[],string[],bytes32[])\":{\"details\":\"Can be used to reveal multiple copies of the same token id\",\"params\":{\"amounts\":\"The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\",\"metadataHashes\":\"The array of hashes for revealed asset metadata\",\"prevTokenId\":\"The tokenId of the unrevealed asset\",\"revealHashes\":\"A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\",\"signature\":\"Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\"}},\"revokeRole(bytes32,address)\":{\"details\":\"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event.\"},\"setTierInstantRevealAllowed(uint8,bool)\":{\"params\":{\"allowed\":\"allow or disallow instant reveal for the given tier\",\"tier\":\"the tier to set the permission for\"}},\"setTrustedForwarder(address)\":{\"details\":\"Change the address of the trusted forwarder for meta-TX\",\"params\":{\"trustedForwarder\":\"The new trustedForwarder\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"title\":\"AssetReveal\",\"version\":1},\"userdoc\":{\"events\":{\"TrustedForwarderSet(address,address,address)\":{\"notice\":\"Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\"}},\"kind\":\"user\",\"methods\":{\"burnAndReveal(bytes,uint256,uint256,uint256[],string[],bytes32[])\":{\"notice\":\"Reveal assets to view their abilities and enhancements and mint them in a single transaction\"},\"getAssetContract()\":{\"notice\":\"Get the asset contract address\"},\"getAuthValidator()\":{\"notice\":\"Get the auth validator address\"},\"getTierInstantRevealAllowed(uint8)\":{\"notice\":\"Get permission for instant reveal for a given tier\"},\"getTrustedForwarder()\":{\"notice\":\"return the address of the trusted forwarder\"},\"initialize(string,string,address,address,address,address)\":{\"notice\":\"Initialize the contract\"},\"isTrustedForwarder(address)\":{\"notice\":\"return true if the forwarder is the trusted forwarder\"},\"pause()\":{\"notice\":\"Pause the contracts mint and burn functions\"},\"revealBatchBurn(uint256[],uint256[])\":{\"notice\":\"Burn multiple assets to be able to reveal them later\"},\"revealBatchMint(bytes,uint256[],uint256[][],string[][],bytes32[][])\":{\"notice\":\"Mint multiple assets with revealed abilities and enhancements\"},\"revealBurn(uint256,uint256)\":{\"notice\":\"Reveal an asset to view its abilities and enhancements\"},\"revealHashUsed(bytes32)\":{\"notice\":\"Get the status of a revealHash\"},\"revealMint(bytes,uint256,uint256[],string[],bytes32[])\":{\"notice\":\"Reveal assets to view their abilities and enhancements\"},\"setTierInstantRevealAllowed(uint8,bool)\":{\"notice\":\"Set permission for instant reveal for a given tier\"},\"setTrustedForwarder(address)\":{\"notice\":\"Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\"},\"unpause()\":{\"notice\":\"Unpause the contracts mint and burn functions\"}},\"notice\":\"Contract for burning and revealing assets\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/asset/contracts/AssetReveal.sol\":\"AssetReveal\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlUpgradeable.sol\\\";\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\\n function __AccessControl_init() internal onlyInitializing {\\n }\\n\\n function __AccessControl_init_unchained() internal onlyInitializing {\\n }\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n StringsUpgradeable.toHexString(account),\\n \\\" is missing role \\\",\\n StringsUpgradeable.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xfeefb24d068524440e1ba885efdf105d91f83504af3c2d745ffacc4595396831\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControlUpgradeable {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xb8f5302f12138c5561362e88a78d061573e6298b7a1a5afe84a1e2c8d4d5aeaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\\n\\npragma solidity ^0.8.0;\\n\\ninterface IERC5267Upgradeable {\\n /**\\n * @dev MAY be emitted to signal that the domain could have changed.\\n */\\n event EIP712DomainChanged();\\n\\n /**\\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\\n * signature.\\n */\\n function eip712Domain()\\n external\\n view\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n );\\n}\\n\",\"keccak256\":\"0xe562dab443278837fa50faddb76743399e942181881db8dccaea3bd1712994db\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n function __Pausable_init() internal onlyInitializing {\\n __Pausable_init_unchained();\\n }\\n\\n function __Pausable_init_unchained() internal onlyInitializing {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x40c636b4572ff5f1dc50cf22097e93c0723ee14eff87e99ac2b02636eeca1250\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\\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\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\\\";\\nimport \\\"./math/SignedMathUpgradeable.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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\":\"0xb96dc79b65b7c37937919dcdb356a969ce0aa2e8338322bf4dc027a3c9c9a7eb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \\\"../StringsUpgradeable.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 ECDSAUpgradeable {\\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\\\", StringsUpgradeable.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\":\"0xa014f65d84b02827055d99993ccdbfb4b56b2c9e91eb278d82a93330659d06e4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\\n\\npragma solidity ^0.8.8;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../interfaces/IERC5267Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\\n bytes32 private constant _TYPE_HASH =\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /// @custom:oz-renamed-from _HASHED_NAME\\n bytes32 private _hashedName;\\n /// @custom:oz-renamed-from _HASHED_VERSION\\n bytes32 private _hashedVersion;\\n\\n string private _name;\\n string private _version;\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n _name = name;\\n _version = version;\\n\\n // Reset prior values in storage if upgrading\\n _hashedName = 0;\\n _hashedVersion = 0;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator();\\n }\\n\\n function _buildDomainSeparator() private view returns (bytes32) {\\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev See {EIP-5267}.\\n *\\n * _Available since v4.9._\\n */\\n function eip712Domain()\\n public\\n view\\n virtual\\n override\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n )\\n {\\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\\n // and the EIP712 domain is not reliable, as it will be missing name and version.\\n require(_hashedName == 0 && _hashedVersion == 0, \\\"EIP712: Uninitialized\\\");\\n\\n return (\\n hex\\\"0f\\\", // 01111\\n _EIP712Name(),\\n _EIP712Version(),\\n block.chainid,\\n address(this),\\n bytes32(0),\\n new uint256[](0)\\n );\\n }\\n\\n /**\\n * @dev The name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Name() internal virtual view returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev The version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Version() internal virtual view returns (string memory) {\\n return _version;\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\\n */\\n function _EIP712NameHash() internal view returns (bytes32) {\\n string memory name = _EIP712Name();\\n if (bytes(name).length > 0) {\\n return keccak256(bytes(name));\\n } else {\\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\\n bytes32 hashedName = _hashedName;\\n if (hashedName != 0) {\\n return hashedName;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\\n */\\n function _EIP712VersionHash() internal view returns (bytes32) {\\n string memory version = _EIP712Version();\\n if (bytes(version).length > 0) {\\n return keccak256(bytes(version));\\n } else {\\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\\n bytes32 hashedVersion = _hashedVersion;\\n if (hashedVersion != 0) {\\n return hashedVersion;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[48] private __gap;\\n}\\n\",\"keccak256\":\"0xeb8d6be406a373771724922eb41b5d593bc8e2dc705daa22cd1145cfc8f5a3a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\\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\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\\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\":\"0x2bc0007987c229ae7624eb29be6a9b84f6a6a5872f76248b15208b131ea41c4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\\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\":\"0x88f6b7bba3ee33eeb741f9a0f5bc98b6e6e352d0fe4905377bb328590f84095a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(account),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0dd6e52cb394d7f5abe5dca2d4908a6be40417914720932de757de34a99ab87f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"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/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\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"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\"},\"@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/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\"},\"@sandbox-smart-contracts/asset/contracts/AssetReveal.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {EIP712Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\\\";\\nimport {\\n AccessControlUpgradeable,\\n ContextUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\\\";\\nimport {PausableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\\\";\\nimport {TokenIdUtils} from \\\"./libraries/TokenIdUtils.sol\\\";\\nimport {AuthSuperValidator} from \\\"./AuthSuperValidator.sol\\\";\\nimport {\\n ERC2771HandlerUpgradeable\\n} from \\\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\\\";\\nimport {IAsset} from \\\"./interfaces/IAsset.sol\\\";\\nimport {IAssetReveal} from \\\"./interfaces/IAssetReveal.sol\\\";\\n\\n/// @title AssetReveal\\n/// @author The Sandbox\\n/// @notice Contract for burning and revealing assets\\ncontract AssetReveal is\\n IAssetReveal,\\n Initializable,\\n AccessControlUpgradeable,\\n ERC2771HandlerUpgradeable,\\n EIP712Upgradeable,\\n PausableUpgradeable\\n{\\n using TokenIdUtils for uint256;\\n IAsset private assetContract;\\n AuthSuperValidator private authValidator;\\n\\n // mapping of creator to asset id to asset's reveal nonce\\n mapping(address => mapping(uint256 => uint16)) internal revealIds;\\n\\n // mapping for showing whether a revealHash has been used\\n // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting\\n mapping(bytes32 => bool) internal revealHashesUsed;\\n\\n // allowance list for tier to be revealed in a single transaction\\n mapping(uint8 => bool) internal tierInstantRevealAllowed;\\n\\n bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n bytes32 public constant REVEAL_TYPEHASH =\\n keccak256(\\n \\\"Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\\\"\\n );\\n bytes32 public constant BATCH_REVEAL_TYPEHASH =\\n keccak256(\\n \\\"BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)\\\"\\n );\\n bytes32 public constant INSTANT_REVEAL_TYPEHASH =\\n keccak256(\\n \\\"InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\\\"\\n );\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @notice Initialize the contract\\n /// @param _assetContract The address of the asset contract\\n /// @param _authValidator The address of the AuthSuperValidator contract\\n /// @param _forwarder The address of the forwarder contract\\n function initialize(\\n string memory _name,\\n string memory _version,\\n address _assetContract,\\n address _authValidator,\\n address _forwarder,\\n address _defaultAdmin\\n ) public initializer {\\n assetContract = IAsset(_assetContract);\\n authValidator = AuthSuperValidator(_authValidator);\\n __ERC2771Handler_init(_forwarder);\\n __EIP712_init(_name, _version);\\n __AccessControl_init();\\n __Pausable_init();\\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\\n }\\n\\n /// @notice Reveal an asset to view its abilities and enhancements\\n /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId\\n /// @param tokenId the tokenId of id idasset to reveal\\n /// @param amount the amount of tokens to reveal\\n function revealBurn(uint256 tokenId, uint256 amount) external whenNotPaused {\\n _burnAsset(tokenId, amount);\\n emit AssetRevealBurn(_msgSender(), tokenId, amount);\\n }\\n\\n /// @notice Burn multiple assets to be able to reveal them later\\n /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately\\n /// @param tokenIds the tokenIds of the assets to burn\\n /// @param amounts the amounts of the assets to burn\\n function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external whenNotPaused {\\n _burnAssetBatch(tokenIds, amounts);\\n emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts);\\n }\\n\\n /// @notice Reveal assets to view their abilities and enhancements\\n /// @dev Can be used to reveal multiple copies of the same token id\\n /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\\n /// @param prevTokenId The tokenId of the unrevealed asset\\n /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\\n /// @param metadataHashes The array of hashes for revealed asset metadata\\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\\n function revealMint(\\n bytes memory signature,\\n uint256 prevTokenId,\\n uint256[] calldata amounts,\\n string[] calldata metadataHashes,\\n bytes32[] calldata revealHashes\\n ) external whenNotPaused {\\n require(amounts.length == metadataHashes.length, \\\"AssetReveal: 1-Array mismatch\\\");\\n require(amounts.length == revealHashes.length, \\\"AssetReveal: 2-Array mismatch\\\");\\n require(\\n authValidator.verify(\\n signature,\\n _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\\n ),\\n \\\"AssetReveal: Invalid signature\\\"\\n );\\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\\n }\\n\\n /// @notice Mint multiple assets with revealed abilities and enhancements\\n /// @dev Can be used to reveal multiple copies of the same token id\\n /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\\n /// @param prevTokenIds The tokenId of the unrevealed asset\\n /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes)\\n /// @param metadataHashes The array of hashes for asset metadata\\n /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\\n function revealBatchMint(\\n bytes calldata signature,\\n uint256[] calldata prevTokenIds,\\n uint256[][] calldata amounts,\\n string[][] calldata metadataHashes,\\n bytes32[][] calldata revealHashes\\n ) external whenNotPaused {\\n require(prevTokenIds.length == amounts.length, \\\"AssetReveal: 1-Array mismatch\\\");\\n require(amounts.length == metadataHashes.length, \\\"AssetReveal: 2-Array mismatch\\\");\\n require(prevTokenIds.length == revealHashes.length, \\\"AssetReveal: 3-Array mismatch\\\");\\n require(\\n authValidator.verify(\\n signature,\\n _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes)\\n ),\\n \\\"AssetReveal: Invalid signature\\\"\\n );\\n uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length);\\n for (uint256 i = 0; i < prevTokenIds.length; i++) {\\n newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]);\\n }\\n emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes);\\n }\\n\\n /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction\\n /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\\n /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\\n /// @param prevTokenId The tokenId of the unrevealed asset\\n /// @param burnAmount The amount of assets to burn\\n /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount)\\n /// @param metadataHashes The array of hashes for asset metadata\\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\\n function burnAndReveal(\\n bytes memory signature,\\n uint256 prevTokenId,\\n uint256 burnAmount,\\n uint256[] calldata amounts,\\n string[] calldata metadataHashes,\\n bytes32[] calldata revealHashes\\n ) external whenNotPaused {\\n require(amounts.length == metadataHashes.length, \\\"AssetReveal: 1-Array mismatch\\\");\\n require(amounts.length == revealHashes.length, \\\"AssetReveal: 2-Array mismatch\\\");\\n uint8 tier = prevTokenId.getTier();\\n require(tierInstantRevealAllowed[tier], \\\"AssetReveal: Not allowed\\\");\\n require(\\n authValidator.verify(\\n signature,\\n _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\\n ),\\n \\\"AssetReveal: Invalid signature\\\"\\n );\\n _burnAsset(prevTokenId, burnAmount);\\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\\n }\\n\\n /// @notice Generate new tokenIds for revealed assets and mint them\\n /// @param prevTokenId The tokenId of the unrevealed asset\\n /// @param metadataHashes The array of hashes for asset metadata\\n /// @param amounts The array of amounts to mint\\n function _revealAsset(\\n uint256 prevTokenId,\\n string[] calldata metadataHashes,\\n uint256[] calldata amounts,\\n bytes32[] calldata revealHashes\\n ) internal returns (uint256[] memory) {\\n uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId);\\n for (uint256 i = 0; i < revealHashes.length; i++) {\\n require(revealHashesUsed[revealHashes[i]] == false, \\\"AssetReveal: Hash already used\\\");\\n revealHashesUsed[revealHashes[i]] = true;\\n }\\n if (newTokenIds.length == 1) {\\n assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]);\\n } else {\\n assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes);\\n }\\n return newTokenIds;\\n }\\n\\n /// @notice Burns an asset to be able to reveal it later\\n /// @param tokenId the tokenId of the asset to burn\\n /// @param amount the amount of the asset to burn\\n function _burnAsset(uint256 tokenId, uint256 amount) internal {\\n _verifyBurnData(tokenId, amount);\\n assetContract.burnFrom(_msgSender(), tokenId, amount);\\n }\\n\\n function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal {\\n require(tokenIds.length == amounts.length, \\\"AssetReveal: Invalid input\\\");\\n for (uint256 i = 0; i < tokenIds.length; i++) {\\n _verifyBurnData(tokenIds[i], amounts[i]);\\n }\\n assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts);\\n }\\n\\n function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure {\\n IAsset.AssetData memory data = tokenId.getData();\\n require(!data.revealed, \\\"AssetReveal: Already revealed\\\");\\n require(amount > 0, \\\"AssetReveal: Invalid amount\\\");\\n }\\n\\n /// @notice Creates a hash of the reveal data\\n /// @param recipient The address of the recipient\\n /// @param prevTokenId The unrevealed token id\\n /// @param amounts The amount of tokens to mint\\n /// @param metadataHashes The array of hashes for new asset metadata\\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\\n /// @return digest The hash of the reveal data\\n function _hashInstantReveal(\\n address recipient,\\n uint256 prevTokenId,\\n uint256[] calldata amounts,\\n string[] calldata metadataHashes,\\n bytes32[] calldata revealHashes\\n ) internal view returns (bytes32 digest) {\\n digest = _hashTypedDataV4(\\n keccak256(\\n abi.encode(\\n INSTANT_REVEAL_TYPEHASH,\\n recipient,\\n prevTokenId,\\n keccak256(abi.encodePacked(amounts)),\\n _encodeHashes(metadataHashes),\\n keccak256(abi.encodePacked(revealHashes))\\n )\\n )\\n );\\n }\\n\\n /// @notice Creates a hash of the reveal data\\n /// @param recipient The intended recipient of the revealed token\\n /// @param prevTokenId The previous token id\\n /// @param amounts The amount of tokens to mint\\n /// @param metadataHashes The array of hashes for new asset metadata\\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\\n /// @return digest The hash of the reveal data\\n function _hashReveal(\\n address recipient,\\n uint256 prevTokenId,\\n uint256[] calldata amounts,\\n string[] calldata metadataHashes,\\n bytes32[] calldata revealHashes\\n ) internal view returns (bytes32 digest) {\\n digest = _hashTypedDataV4(\\n keccak256(\\n abi.encode(\\n REVEAL_TYPEHASH,\\n recipient,\\n prevTokenId,\\n keccak256(abi.encodePacked(amounts)),\\n _encodeHashes(metadataHashes),\\n keccak256(abi.encodePacked(revealHashes))\\n )\\n )\\n );\\n }\\n\\n /// @notice Creates a hash of the reveal data\\n /// @param recipient The intended recipient of the revealed tokens\\n /// @param prevTokenIds The previous token id\\n /// @param amounts The amounts of tokens to mint\\n /// @param metadataHashes The arrays of hashes for new asset metadata\\n /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds)\\n /// @return digest The hash of the reveal data\\n function _hashBatchReveal(\\n address recipient,\\n uint256[] calldata prevTokenIds,\\n uint256[][] calldata amounts,\\n string[][] calldata metadataHashes,\\n bytes32[][] calldata revealHashes\\n ) internal view returns (bytes32 digest) {\\n digest = _hashTypedDataV4(\\n keccak256(\\n abi.encode(\\n BATCH_REVEAL_TYPEHASH,\\n recipient,\\n keccak256(abi.encodePacked(prevTokenIds)),\\n _encodeBatchAmounts(amounts),\\n _encodeBatchHashes(metadataHashes),\\n _encodeBatchRevealHashes(revealHashes)\\n )\\n )\\n );\\n }\\n\\n /// @notice Encodes the hashes of the metadata for signature verification\\n /// @param metadataHashes The hashes of the metadata\\n /// @return encodedHashes The encoded hashes of the metadata\\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\\n for (uint256 i = 0; i < metadataHashes.length; i++) {\\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\\n }\\n return keccak256(abi.encodePacked(encodedHashes));\\n }\\n\\n /// @notice Encodes the hashes of the metadata for signature verification\\n /// @param metadataHashes The hashes of the metadata\\n /// @return encodedHashes The encoded hashes of the metadata\\n function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) {\\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\\n for (uint256 i = 0; i < metadataHashes.length; i++) {\\n encodedHashes[i] = _encodeHashes(metadataHashes[i]);\\n }\\n return keccak256(abi.encodePacked(encodedHashes));\\n }\\n\\n /// @notice Encodes the hashes of the metadata for signature verification\\n /// @param revealHashes The revealHashes\\n /// @return encodedRevealHashes The encoded hashes of the metadata\\n function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) {\\n bytes32[] memory encodedHashes = new bytes32[](revealHashes.length);\\n for (uint256 i = 0; i < revealHashes.length; i++) {\\n encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i]));\\n }\\n return keccak256(abi.encodePacked(encodedHashes));\\n }\\n\\n /// @notice Encodes the amounts of the tokens for signature verification\\n /// @param amounts The amounts of the tokens\\n /// @return encodedAmounts The encoded amounts of the tokens\\n function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) {\\n bytes32[] memory encodedAmounts = new bytes32[](amounts.length);\\n for (uint256 i = 0; i < amounts.length; i++) {\\n encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i]));\\n }\\n return keccak256(abi.encodePacked(encodedAmounts));\\n }\\n\\n /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't\\n /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed\\n /// @param metadataHashes The hashes of the metadata\\n /// @param prevTokenId The previous token id from which the assets are revealed\\n /// @return tokenIds The array of tokenIds to mint\\n function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId)\\n internal\\n returns (uint256[] memory tokenIds)\\n {\\n IAsset.AssetData memory data = prevTokenId.getData();\\n require(!data.revealed, \\\"AssetReveal: Already revealed\\\");\\n uint256[] memory tokenIdArray = new uint256[](metadataHashes.length);\\n for (uint256 i = 0; i < metadataHashes.length; i++) {\\n uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]);\\n if (tokenId == 0) {\\n uint16 revealNonce = ++revealIds[data.creator][prevTokenId];\\n tokenId = TokenIdUtils.generateTokenId(\\n data.creator,\\n data.tier,\\n data.creatorNonce,\\n revealNonce,\\n data.bridged\\n );\\n }\\n tokenIdArray[i] = tokenId;\\n }\\n return tokenIdArray;\\n }\\n\\n /// @notice Get the status of a revealHash\\n /// @return hashUsed Boolean representing whether the hash has been used\\n function revealHashUsed(bytes32 revealHash) external view returns (bool hashUsed) {\\n return revealHashesUsed[revealHash];\\n }\\n\\n /// @notice Get the asset contract address\\n /// @return assetContractAddres The asset contract address\\n function getAssetContract() external view returns (address assetContractAddres) {\\n return address(assetContract);\\n }\\n\\n /// @notice Get the auth validator address\\n /// @return authValidatorContractAddress The auth validator address\\n function getAuthValidator() external view returns (address authValidatorContractAddress) {\\n return address(authValidator);\\n }\\n\\n /// @notice Set permission for instant reveal for a given tier\\n /// @param tier the tier to set the permission for\\n /// @param allowed allow or disallow instant reveal for the given tier\\n function setTierInstantRevealAllowed(uint8 tier, bool allowed) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n tierInstantRevealAllowed[tier] = allowed;\\n }\\n\\n /// @notice Get permission for instant reveal for a given tier\\n /// @param tier The tier to check\\n /// @return instantRevealAllowed Boolean representing whether instant reveal is allowed for the given tier\\n function getTierInstantRevealAllowed(uint8 tier) external view returns (bool instantRevealAllowed) {\\n return tierInstantRevealAllowed[tier];\\n }\\n\\n /// @notice Pause the contracts mint and burn functions\\n function pause() external onlyRole(PAUSER_ROLE) {\\n _pause();\\n }\\n\\n /// @notice Unpause the contracts mint and burn functions\\n function unpause() external onlyRole(PAUSER_ROLE) {\\n _unpause();\\n }\\n\\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\\n /// @dev Change the address of the trusted forwarder for meta-TX\\n /// @param trustedForwarder The new trustedForwarder\\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(trustedForwarder != address(0), \\\"AssetReveal: Zero address\\\");\\n _setTrustedForwarder(trustedForwarder);\\n }\\n\\n function _msgSender()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (address sender)\\n {\\n return ERC2771HandlerUpgradeable._msgSender();\\n }\\n\\n function _msgData()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (bytes calldata)\\n {\\n return ERC2771HandlerUpgradeable._msgData();\\n }\\n}\\n\",\"keccak256\":\"0x2db1a9af9e6957908f10b724f9a55c25fb0c2b9cc0ff746e517b9ef2263f8c0e\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {AccessControl} from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\n\\n/// @title AuthSuperValidator\\n/// @author The Sandbox\\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\\ncontract AuthSuperValidator is AccessControl {\\n mapping(address => address) private _signers;\\n\\n /// @dev Constructor\\n /// @param admin Address of the admin that will be able to grant roles\\n constructor(address admin) {\\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\\n }\\n\\n /// @notice Sets the signer for a contract\\n /// @dev Only the admin can call this function\\n /// @param contractAddress Address of the contract to set the signer for\\n /// @param signer Address of the signer\\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\\n _signers[contractAddress] = signer;\\n }\\n\\n /// @notice Gets the signer for a contract\\n /// @param contractAddress Address of the contract to get the signer for\\n /// @return address of the signer\\n function getSigner(address contractAddress) public view returns (address) {\\n return _signers[contractAddress];\\n }\\n\\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\\n /// @dev Multipurpose function that can be used to verify signatures with different digests\\n /// @param signature Signature hash\\n /// @param digest Digest hash\\n /// @return bool\\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\\n address signer = _signers[_msgSender()];\\n require(signer != address(0), \\\"AuthSuperValidator: No signer\\\");\\n address recoveredSigner = ECDSA.recover(digest, signature);\\n return recoveredSigner == signer;\\n }\\n\\n /// @notice Prevents the DEFAULT_ADMIN_ROLE from being renounced\\n /// @dev This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced\\n /// @param role Role to renounce\\n /// @param account Account to renounce the role for\\n function renounceRole(bytes32 role, address account) public override {\\n require(role != DEFAULT_ADMIN_ROLE, \\\"AuthSuperValidator: cant renounce admin role\\\");\\n super.renounceRole(role, account);\\n }\\n}\\n\",\"keccak256\":\"0xd285d5edbc7bedd8dbc3341af44c05ff3bc204ec2e4b6d7bffcd9bb91de3f141\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/// @title Asset interface\\n/// @author The Sandbox\\ninterface IAsset {\\n // AssetData reflects the asset tokenId structure\\n // Refer to TokenIdUtils.sol\\n struct AssetData {\\n uint256 tokenId;\\n address creator;\\n uint256 amount;\\n uint8 tier;\\n uint16 creatorNonce;\\n bool revealed;\\n string metadataHash;\\n bool bridged;\\n }\\n\\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\\n\\n /// @notice Mint new tokens\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param id The id of the token to mint\\n /// @param amount The amount of the token to mint\\n /// @param metadataHash The metadata hash of the token to mint\\n function mint(\\n address to,\\n uint256 id,\\n uint256 amount,\\n string memory metadataHash\\n ) external;\\n\\n /// @notice Mint new tokens with catalyst tier chosen by the creator\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param ids The ids of the tokens to mint\\n /// @param amounts The amounts of the tokens to mint\\n /// @param metadataHashes The metadata hashes of the tokens to mint\\n function mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n string[] memory metadataHashes\\n ) external;\\n\\n /// @notice Burn a token from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @param account The account to burn tokens from\\n /// @param id The token id to burn\\n /// @param amount The amount of tokens to burn\\n function burnFrom(\\n address account,\\n uint256 id,\\n uint256 amount\\n ) external;\\n\\n /// @notice Burn a batch of tokens from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @dev The length of the ids and amounts arrays must be the same\\n /// @param account The account to burn tokens from\\n /// @param ids An array of token ids to burn\\n /// @param amounts An array of amounts of tokens to burn\\n function burnBatchFrom(\\n address account,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external;\\n\\n /// @notice returns the tokenId associated with provided metadata hash\\n /// @param metadataHash The metadata hash to get tokenId for\\n /// @return tokenId the tokenId associated with the metadata hash\\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256 tokenId);\\n}\\n\",\"keccak256\":\"0xbc79058becff31b0b7f465d92a89aad25f561dbdb5a2cd068d51c7ef93b4fbfe\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/IAssetReveal.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/// @title AssetReveal interface\\n/// @author The Sandbox\\ninterface IAssetReveal {\\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\\n event AssetRevealBurn(address indexed revealer, uint256 unrevealedTokenId, uint256 amount);\\n event AssetRevealBatchBurn(address indexed revealer, uint256[] unrevealedTokenIds, uint256[] amounts);\\n event AssetRevealMint(\\n address indexed recipient,\\n uint256 unrevealedTokenId,\\n uint256[] amounts,\\n uint256[] newTokenIds,\\n bytes32[] revealHashes\\n );\\n event AssetRevealBatchMint(\\n address indexed recipient,\\n uint256[] unrevealedTokenIds,\\n uint256[][] amounts,\\n uint256[][] newTokenIds,\\n bytes32[][] revealHashes\\n );\\n}\\n\",\"keccak256\":\"0xbc789e816dc6abab09c2bbaa5e7d753b5d972a17265198984caf5fa6fe5bb4ce\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IAsset} from \\\"../interfaces/IAsset.sol\\\";\\n\\n/// @title TokenIdUtils library\\n/// @author The Sandbox\\n/// @notice Contains utility functions for token ids\\nlibrary TokenIdUtils {\\n // Layer masks\\n uint256 public constant TIER_MASK = 0xFF;\\n uint256 public constant NONCE_MASK = 0xFFFF;\\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\\n uint256 public constant BRIDGED_MASK = 0x1;\\n\\n // Bit shifts\\n uint256 public constant CREATOR_SHIFT = 0;\\n uint256 public constant TIER_SHIFT = 160;\\n uint256 public constant NONCE_SHIFT = 168;\\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\\n uint256 public constant BRIDGED_SHIFT = 200;\\n\\n /// @notice Generates a token id for a given asset\\n /// @dev The token id is generated by concatenating the following fields:\\n /// @dev creator address, tier, creator nonce, reveal nonce and bridged boolean\\n /// @dev The first 160 bits are the creator address\\n /// @dev The next 8 bits are the tier\\n /// @dev The next 16 bits are the creator nonce\\n /// @dev The next 16 bits are for reveal nonce.\\n /// @dev The last bit is for bridged boolean\\n /// @param creator The address of the creator of the asset\\n /// @param tier The tier of the asset determined by the catalyst used to create it\\n /// @param creatorNonce The nonce of the asset creator\\n /// @param revealNonce The reveal nonce of the asset\\n /// @param bridged Whether the asset is bridged or not\\n /// @return tokenId The generated token id\\n function generateTokenId(\\n address creator,\\n uint8 tier,\\n uint16 creatorNonce,\\n uint16 revealNonce,\\n bool bridged\\n ) internal pure returns (uint256 tokenId) {\\n uint160 creatorAddress = uint160(creator);\\n\\n tokenId = tokenId =\\n uint256(creatorAddress) |\\n (uint256(tier) << TIER_SHIFT) |\\n (uint256(creatorNonce) << NONCE_SHIFT) |\\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\\n\\n return tokenId;\\n }\\n\\n /// @notice Extracts the creator address from a given token id\\n /// @param tokenId The token id to extract the creator address from\\n /// @return creator The asset creator address\\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\\n creator = address(uint160(tokenId));\\n return creator;\\n }\\n\\n /// @notice Extracts the tier from a given token id\\n /// @param tokenId The token id to extract the tier from\\n /// @return tier The asset tier, determined by the catalyst used to create it\\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\\n return tier;\\n }\\n\\n /// @notice Extracts the revealed flag from a given token id\\n /// @param tokenId The token id to extract the revealed flag from\\n /// @return isRevealed Whether the asset is revealed or not\\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\\n uint16 revealNonce = getRevealNonce(tokenId);\\n return revealNonce != 0;\\n }\\n\\n /// @notice Extracts the asset nonce from a given token id\\n /// @param tokenId The token id to extract the asset nonce from\\n /// @return creatorNonce The asset creator nonce\\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\\n return creatorNonce;\\n }\\n\\n /// @notice Extracts the abilities and enhancements hash from a given token id\\n /// @param tokenId The token id to extract reveal nonce from\\n /// @return revealNonce The reveal nonce of the asset\\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\\n return revealNonce;\\n }\\n\\n /// @notice Extracts the bridged flag from a given token id\\n /// @param tokenId The token id to extract the bridged flag from\\n /// @return bridged Whether the asset is bridged or not\\n function isBridged(uint256 tokenId) internal pure returns (bool) {\\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\\n return bridged;\\n }\\n\\n /// @notice Extracts the asset data from a given token id\\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\\n /// @param tokenId The token id to extract the asset data from\\n /// @return data The asset data struct\\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\\n data.creator = getCreatorAddress(tokenId);\\n data.tier = getTier(tokenId);\\n data.revealed = isRevealed(tokenId);\\n data.creatorNonce = getCreatorNonce(tokenId);\\n data.bridged = isBridged(tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x68a7d6f1ff700f2c1cc9b20e89ccd9aa7fced45a54cc1e3c361136c57d0e4511\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\nabstract contract ERC2771HandlerAbstract {\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function isTrustedForwarder(address forwarder) external view returns (bool) {\\n return _isTrustedForwarder(forwarder);\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual returns (address sender) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n // The assembly code is more direct than the Solidity version using `abi.decode`.\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\\n }\\n } else {\\n sender = msg.sender;\\n }\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual returns (bytes calldata) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n return msg.data[:msg.data.length - 20];\\n } else {\\n return msg.data;\\n }\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n /// @dev this function must be IMPLEMENTED\\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xc4f349865ea7146f51b69f1edacdef60e0a2a7cf4dab538a5ae53ee9a0036231\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {ERC2771HandlerAbstract} from \\\"./ERC2771HandlerAbstract.sol\\\";\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\\n address private _trustedForwarder;\\n\\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\\n /// @param oldTrustedForwarder old trusted forwarder\\n /// @param newTrustedForwarder new trusted forwarder\\n /// @param operator the sender of the transaction\\n event TrustedForwarderSet(\\n address indexed oldTrustedForwarder,\\n address indexed newTrustedForwarder,\\n address indexed operator\\n );\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\\n __ERC2771Handler_init_unchained(forwarder);\\n }\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\\n _setTrustedForwarder(forwarder);\\n }\\n\\n /// @notice return the address of the trusted forwarder\\n /// @return return the address of the trusted forwarder\\n function getTrustedForwarder() external view returns (address) {\\n return _trustedForwarder;\\n }\\n\\n /// @notice set the address of the trusted forwarder\\n /// @param newForwarder the address of the new forwarder.\\n function _setTrustedForwarder(address newForwarder) internal virtual {\\n require(newForwarder != _trustedForwarder, \\\"ERC2771HandlerUpgradeable: forwarder already set\\\");\\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\\n _trustedForwarder = newForwarder;\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\\n return forwarder == _trustedForwarder;\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual override returns (address sender) {\\n return super._msgSender();\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual override returns (bytes calldata) {\\n return super._msgData();\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf9767f843906800128ee86bd89bc2088e8f1b633ed4c800f477beb4e604f81de\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b613cea80620000f36000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806384b0196e11610104578063d547741f116100a2578063e63ab1e911610071578063e63ab1e914610432578063e72cbd5314610459578063ecc0382a14610480578063f30553d51461049357600080fd5b8063d547741f146103e7578063d5f2077c146103fa578063da7422281461040c578063e56f2fe41461041f57600080fd5b8063a217fddf116100de578063a217fddf14610383578063b21c2cdc1461038b578063bd2cc82a146103b2578063ce1b815f146103d657600080fd5b806384b0196e1461031c57806391d14854146103375780639d9d91f61461037057600080fd5b80633f4ba83a1161017157806359c191e41161014b57806359c191e4146102d05780635aaa24bf146102f65780635c975abb146103095780638456cb591461031457600080fd5b80633f4ba83a146102a2578063439ff3ce146102aa578063572b6c05146102bd57600080fd5b8063248a9ca3116101ad578063248a9ca3146102245780632f2ff15d1461025557806336568abe146102685780633a2cf31a1461027b57600080fd5b806301ffc9a7146101d45780630c85fbb3146101fc57806310da539314610211575b600080fd5b6101e76101e2366004612ad4565b6104ba565b60405190151581526020015b60405180910390f35b61020f61020a366004612b62565b610553565b005b61020f61021f366004612c85565b6105bb565b610247610232366004612d4d565b60009081526065602052604090206001015490565b6040519081526020016101f3565b61020f610263366004612d82565b6107aa565b61020f610276366004612d82565b6107d4565b6102477f1d2951170e2f5d8eb8a7a48a737f5f1680469c14594abd27536867bfb559f88f81565b61020f610870565b61020f6102b8366004612df0565b6108a5565b6101e76102cb366004612ee1565b610bec565b61012f546001600160a01b03165b6040516001600160a01b0390911681526020016101f3565b61020f610304366004612efc565b610c06565b60fd5460ff166101e7565b61020f610c6f565b610324610ca1565b6040516101f39796959493929190612fa9565b6101e7610345366004612d82565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61020f61037e366004613044565b610d63565b610247600081565b6102477f45cf7a9b20b47d492887b813085b48aa1988f1f482fe79948578452b4b4cbedd81565b6101e76103c0366004612d4d565b6000908152610132602052604090205460ff1690565b6097546001600160a01b03166102de565b61020f6103f5366004612d82565b610d95565b610130546001600160a01b03166102de565b61020f61041a366004612ee1565b610dba565b61020f61042d36600461307b565b610e24565b6102477f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6101e7610467366004613120565b60ff908116600090815261013360205260409020541690565b61020f61048e36600461313b565b610fba565b6102477f30ed1d13f34eab3b4d1a3291d48db1d77bbc98ec9480b9131e4360220fd46fb081565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061054d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61055b61120f565b61056784848484611264565b61056f611381565b6001600160a01b03167f25601c42b4517e81abacb7c77cd6d6697ea55465121e953721d60becc43b88e2858585856040516105ad949392919061325a565b60405180910390a250505050565b6105c361120f565b8483146106175760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20312d4172726179206d69736d6174636800000060448201526064015b60405180910390fd5b8481146106665760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20322d4172726179206d69736d61746368000000604482015260640161060e565b610130546001600160a01b0316636b40634189610690610684611381565b8b8b8b8b8b8b8b611390565b6040518363ffffffff1660e01b81526004016106ad92919061328c565b602060405180830381865afa1580156106ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ee91906132ae565b61073a5760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a20496e76616c6964207369676e61747572650000604482015260640161060e565b600061074b8886868a8a888861147f565b9050610755611381565b6001600160a01b03167fd19ae26d53e6e3446633338937b673d431c042f61b32854f821bc2b2b025b2c4898989858888604051610797969594939291906132cb565b60405180910390a2505050505050505050565b6000828152606560205260409020600101546107c5816116c8565b6107cf83836116d9565b505050565b6107dc611381565b6001600160a01b0316816001600160a01b0316146108625760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161060e565b61086c828261177c565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a61089a816116c8565b6108a261181d565b50565b6108ad61120f565b8685146108fc5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20312d4172726179206d69736d61746368000000604482015260640161060e565b84831461094b5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20322d4172726179206d69736d61746368000000604482015260640161060e565b86811461099a5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20332d4172726179206d69736d61746368000000604482015260640161060e565b610130546001600160a01b0316636b4063418b8b6109c66109b9611381565b8d8d8d8d8d8d8d8d611875565b6040518463ffffffff1660e01b81526004016109e493929190613337565b602060405180830381865afa158015610a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2591906132ae565b610a715760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a20496e76616c6964207369676e61747572650000604482015260640161060e565b60008767ffffffffffffffff811115610a8c57610a8c612bce565b604051908082528060200260200182016040528015610abf57816020015b6060815260200190600190039081610aaa5790505b50905060005b88811015610b8a57610b5a8a8a83818110610ae257610ae261335b565b90506020020135878784818110610afb57610afb61335b565b9050602002810190610b0d9190613371565b8b8b86818110610b1f57610b1f61335b565b9050602002810190610b319190613371565b898988818110610b4357610b4361335b565b9050602002810190610b559190613371565b61147f565b828281518110610b6c57610b6c61335b565b60200260200101819052508080610b82906133d1565b915050610ac5565b50610b93611381565b6001600160a01b03167f9327e7d8f5446a92ddcaf7ccd64ad67693773944fe2db95200e2d4db200543598a8a8a8a868989604051610bd79796959493929190613491565b60405180910390a25050505050505050505050565b600061054d826097546001600160a01b0391821691161490565b610c0e61120f565b610c188282611948565b610c20611381565b6001600160a01b03167f529140d9ae57da9c5515c8fe288c3865d4cbb81cb143062f99a466cb4bb6fa958383604051610c63929190918252602082015260400190565b60405180910390a25050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c99816116c8565b6108a26119ef565b60006060806000806000606060c9546000801b148015610cc1575060ca54155b610d0d5760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a65640000000000000000000000604482015260640161060e565b610d15611a2d565b610d1d611abf565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b6000610d6e816116c8565b5060ff91909116600090815261013360205260409020805460ff1916911515919091179055565b600082815260656020526040902060010154610db0816116c8565b6107cf838361177c565b6000610dc5816116c8565b6001600160a01b038216610e1b5760405162461bcd60e51b815260206004820152601960248201527f417373657452657665616c3a205a65726f206164647265737300000000000000604482015260640161060e565b61086c82611ace565b600054610100900460ff1615808015610e445750600054600160ff909116105b80610e5e5750303b158015610e5e575060005460ff166001145b610ed05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060e565b6000805460ff191660011790558015610ef3576000805461ff0019166101001790555b61012f80546001600160a01b038088167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255610130805492871692909116919091179055610f4683611bd2565b610f508787611c46565b610f58611cbb565b610f60611d26565b610f6b6000836116d9565b8015610fb1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b610fc261120f565b8483146110115760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20312d4172726179206d69736d61746368000000604482015260640161060e565b8481146110605760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20322d4172726179206d69736d61746368000000604482015260640161060e565b600061106f8960a01c60ff1690565b60ff80821660009081526101336020526040902054919250166110d45760405162461bcd60e51b815260206004820152601860248201527f417373657452657665616c3a204e6f7420616c6c6f7765640000000000000000604482015260640161060e565b610130546001600160a01b0316636b4063418b6110fe6110f2611381565b8d8c8c8c8c8c8c611d99565b6040518363ffffffff1660e01b815260040161111b92919061328c565b602060405180830381865afa158015611138573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115c91906132ae565b6111a85760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a20496e76616c6964207369676e61747572650000604482015260640161060e565b6111b28989611948565b60006111c38a87878b8b898961147f565b90506111cd611381565b6001600160a01b03167fd19ae26d53e6e3446633338937b673d431c042f61b32854f821bc2b2b025b2c48b8a8a858989604051610bd7969594939291906132cb565b60fd5460ff16156112625760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161060e565b565b8281146112b35760405162461bcd60e51b815260206004820152601a60248201527f417373657452657665616c3a20496e76616c696420696e707574000000000000604482015260640161060e565b60005b8381101561130a576112f88585838181106112d3576112d361335b565b905060200201358484848181106112ec576112ec61335b565b90506020020135611dd4565b80611302816133d1565b9150506112b6565b5061012f546001600160a01b03166320820ec3611325611381565b868686866040518663ffffffff1660e01b8152600401611349959493929190613577565b600060405180830381600087803b15801561136357600080fd5b505af1158015611377573d6000803e3d6000fd5b5050505050505050565b600061138b611e83565b905090565b60006114727f1d2951170e2f5d8eb8a7a48a737f5f1680469c14594abd27536867bfb559f88f8a8a8a8a6040516020016113cb9291906135ef565b60408051601f1981840301815291905280516020909101206113f56113f08a8c6136a1565b611e8d565b88886040516020016114089291906135ef565b60408051601f198184030181528282528051602091820120908301979097526001600160a01b03909516948101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120611f81565b9998505050505050505050565b6060600061148e88888b611fc9565b905060005b838110156115745761013260008686848181106114b2576114b261335b565b602090810292909201358352508101919091526040016000205460ff161561151c5760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a204861736820616c726561647920757365640000604482015260640161060e565b600161013260008787858181106115355761153561335b565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061156c906133d1565b915050611493565b5080516001036116495761012f546001600160a01b031663bb7fde71611598611381565b836000815181106115ab576115ab61335b565b6020026020010151898960008181106115c6576115c661335b565b905060200201358c8c60008181106115e0576115e061335b565b90506020028101906115f291906136ae565b6040518663ffffffff1660e01b81526004016116129594939291906136f5565b600060405180830381600087803b15801561162c57600080fd5b505af1158015611640573d6000803e3d6000fd5b505050506116bc565b61012f546001600160a01b031663a55784ef611663611381565b8389898d8d6040518763ffffffff1660e01b815260040161168996959493929190613724565b600060405180830381600087803b1580156116a357600080fd5b505af11580156116b7573d6000803e3d6000fd5b505050505b98975050505050505050565b6108a2816116d4611381565b6121cc565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff1661086c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611738611381565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff161561086c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191690556117d9611381565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b611825612241565b60fd805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611858611381565b6040516001600160a01b03909116815260200160405180910390a1565b600061193a7f30ed1d13f34eab3b4d1a3291d48db1d77bbc98ec9480b9131e4360220fd46fb08b8b8b6040516020016118af9291906135ef565b60408051601f1981840301815291905280516020909101206118d96118d48b8d6137f8565b612293565b6118eb6118e68a8c6138be565b612357565b6118fd6118f8898b613946565b6123fd565b6040805160208101979097526001600160a01b03909516948601949094526060850192909252608084015260a083015260c082015260e001611457565b9a9950505050505050505050565b6119528282611dd4565b61012f546001600160a01b031663124d91e561196c611381565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024810185905260448101849052606401600060405180830381600087803b1580156119d357600080fd5b505af11580156119e7573d6000803e3d6000fd5b505050505050565b6119f761120f565b60fd805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611858611381565b606060cb8054611a3c906139ff565b80601f0160208091040260200160405190810160405280929190818152602001828054611a68906139ff565b8015611ab55780601f10611a8a57610100808354040283529160200191611ab5565b820191906000526020600020905b815481529060010190602001808311611a9857829003601f168201915b5050505050905090565b606060cc8054611a3c906139ff565b6097546001600160a01b0390811690821603611b525760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c72656164792073657400000000000000000000000000000000606482015260840161060e565b611b5a611381565b6097546040516001600160a01b03928316928481169216907f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e590600090a4609780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600054610100900460ff16611c3d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b6108a2816124c1565b600054610100900460ff16611cb15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b61086c8282612535565b600054610100900460ff166112625760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b600054610100900460ff16611d915760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b6112626125c8565b60006114727f45cf7a9b20b47d492887b813085b48aa1988f1f482fe79948578452b4b4cbedd8a8a8a8a6040516020016113cb9291906135ef565b6000611ddf8361263f565b90508060a0015115611e335760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20416c72656164792072657665616c6564000000604482015260640161060e565b600082116107cf5760405162461bcd60e51b815260206004820152601b60248201527f417373657452657665616c3a20496e76616c696420616d6f756e740000000000604482015260640161060e565b600061138b6126cc565b600080825167ffffffffffffffff811115611eaa57611eaa612bce565b604051908082528060200260200182016040528015611ed3578160200160208202803683370190505b50905060005b8351811015611f5157838181518110611ef457611ef461335b565b6020026020010151604051602001611f0c9190613a39565b60405160208183030381529060405280519060200120828281518110611f3457611f3461335b565b602090810291909101015280611f49816133d1565b915050611ed9565b5080604051602001611f639190613a55565b60405160208183030381529060405280519060200120915050919050565b600061054d611f8e61271f565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b60606000611fd68361263f565b90508060a001511561202a5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20416c72656164792072657665616c6564000000604482015260640161060e565b60008467ffffffffffffffff81111561204557612045612bce565b60405190808252806020026020018201604052801561206e578160200160208202803683370190505b50905060005b858110156121c25761012f546000906001600160a01b031663fdda1d0e8989858181106120a3576120a361335b565b90506020028101906120b591906136ae565b6040518363ffffffff1660e01b81526004016120d2929190613a8b565b602060405180830381865afa1580156120ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121139190613a9f565b905080600003612191576020808501516001600160a01b0316600090815261013182526040808220898352909252908120805482906121559061ffff16613ab8565b91906101000a81548161ffff021916908361ffff1602179055905061218d856020015186606001518760800151848960e00151612729565b9150505b808383815181106121a4576121a461335b565b602090810291909101015250806121ba816133d1565b915050612074565b5095945050505050565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff1661086c576121ff81612776565b61220a836020612788565b60405160200161221b929190613ad9565b60408051601f198184030181529082905262461bcd60e51b825261060e91600401613b5a565b60fd5460ff166112625760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161060e565b600080825167ffffffffffffffff8111156122b0576122b0612bce565b6040519080825280602002602001820160405280156122d9578160200160208202803683370190505b50905060005b8351811015611f51578381815181106122fa576122fa61335b565b60200260200101516040516020016123129190613a55565b6040516020818303038152906040528051906020012082828151811061233a5761233a61335b565b60209081029190910101528061234f816133d1565b9150506122df565b600080825167ffffffffffffffff81111561237457612374612bce565b60405190808252806020026020018201604052801561239d578160200160208202803683370190505b50905060005b8351811015611f51576123ce8482815181106123c1576123c161335b565b6020026020010151611e8d565b8282815181106123e0576123e061335b565b6020908102919091010152806123f5816133d1565b9150506123a3565b600080825167ffffffffffffffff81111561241a5761241a612bce565b604051908082528060200260200182016040528015612443578160200160208202803683370190505b50905060005b8351811015611f51578381815181106124645761246461335b565b602002602001015160405160200161247c9190613a55565b604051602081830303815290604052805190602001208282815181106124a4576124a461335b565b6020908102919091010152806124b9816133d1565b915050612449565b600054610100900460ff1661252c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b6108a281611ace565b600054610100900460ff166125a05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b60cb6125ac8382613bb3565b5060cc6125b98282613bb3565b5050600060c981905560ca5550565b600054610100900460ff166126335760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b60fd805460ff19169055565b604080516101008101825260008082529181018290526080810182905260a0808201839052606060c0830181905260e08301939093526001600160a01b038416602083015283901c60ff169181019190915261269a826129b8565b151560a08201526126af8260a81c61ffff1690565b61ffff16608082015260c89190911c60019081161460e082015290565b6097546000906001600160a01b0316331480156126ea575060143610155b1561271a57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600061138b6129d6565b60008560c88361273a57600061273d565b60015b60ff16901b60b88561ffff16901b60a88761ffff16901b60a08960ff16901b846001600160a01b03161717171791505095945050505050565b606061054d6001600160a01b03831660145b60606000612797836002613c73565b6127a2906002613c8a565b67ffffffffffffffff8111156127ba576127ba612bce565b6040519080825280601f01601f1916602001820160405280156127e4576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061281b5761281b61335b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061287e5761287e61335b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006128ba846002613c73565b6128c5906001613c8a565b90505b6001811115612962577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106129065761290661335b565b1a60f81b82828151811061291c5761291c61335b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361295b81613c9d565b90506128c8565b5083156129b15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161060e565b9392505050565b6000806129c98360b81c61ffff1690565b61ffff1615159392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612a01612a4a565b612a09612aa3565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b600080612a55611a2d565b805190915015612a6c578051602090910120919050565b60c9548015612a7b5792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b600080612aae611abf565b805190915015612ac5578051602090910120919050565b60ca548015612a7b5792915050565b600060208284031215612ae657600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146129b157600080fd5b60008083601f840112612b2857600080fd5b50813567ffffffffffffffff811115612b4057600080fd5b6020830191508360208260051b8501011115612b5b57600080fd5b9250929050565b60008060008060408587031215612b7857600080fd5b843567ffffffffffffffff80821115612b9057600080fd5b612b9c88838901612b16565b90965094506020870135915080821115612bb557600080fd5b50612bc287828801612b16565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612c0d57612c0d612bce565b604052919050565b600082601f830112612c2657600080fd5b813567ffffffffffffffff811115612c4057612c40612bce565b612c536020601f19601f84011601612be4565b818152846020838601011115612c6857600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060a0898b031215612ca157600080fd5b883567ffffffffffffffff80821115612cb957600080fd5b612cc58c838d01612c15565b995060208b0135985060408b0135915080821115612ce257600080fd5b612cee8c838d01612b16565b909850965060608b0135915080821115612d0757600080fd5b612d138c838d01612b16565b909650945060808b0135915080821115612d2c57600080fd5b50612d398b828c01612b16565b999c989b5096995094979396929594505050565b600060208284031215612d5f57600080fd5b5035919050565b80356001600160a01b0381168114612d7d57600080fd5b919050565b60008060408385031215612d9557600080fd5b82359150612da560208401612d66565b90509250929050565b60008083601f840112612dc057600080fd5b50813567ffffffffffffffff811115612dd857600080fd5b602083019150836020828501011115612b5b57600080fd5b60008060008060008060008060008060a08b8d031215612e0f57600080fd5b8a3567ffffffffffffffff80821115612e2757600080fd5b612e338e838f01612dae565b909c509a5060208d0135915080821115612e4c57600080fd5b612e588e838f01612b16565b909a50985060408d0135915080821115612e7157600080fd5b612e7d8e838f01612b16565b909850965060608d0135915080821115612e9657600080fd5b612ea28e838f01612b16565b909650945060808d0135915080821115612ebb57600080fd5b50612ec88d828e01612b16565b915080935050809150509295989b9194979a5092959850565b600060208284031215612ef357600080fd5b6129b182612d66565b60008060408385031215612f0f57600080fd5b50508035926020909101359150565b60005b83811015612f39578181015183820152602001612f21565b50506000910152565b60008151808452612f5a816020860160208601612f1e565b601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b83811015612f9e57815187529582019590820190600101612f82565b509495945050505050565b7fff000000000000000000000000000000000000000000000000000000000000008816815260e060208201526000612fe460e0830189612f42565b8281036040840152612ff68189612f42565b90508660608401526001600160a01b03861660808401528460a084015282810360c084015261193a8185612f6e565b803560ff81168114612d7d57600080fd5b80151581146108a257600080fd5b6000806040838503121561305757600080fd5b61306083613025565b9150602083013561307081613036565b809150509250929050565b60008060008060008060c0878903121561309457600080fd5b863567ffffffffffffffff808211156130ac57600080fd5b6130b88a838b01612c15565b975060208901359150808211156130ce57600080fd5b506130db89828a01612c15565b9550506130ea60408801612d66565b93506130f860608801612d66565b925061310660808801612d66565b915061311460a08801612d66565b90509295509295509295565b60006020828403121561313257600080fd5b6129b182613025565b600080600080600080600080600060c08a8c03121561315957600080fd5b893567ffffffffffffffff8082111561317157600080fd5b61317d8d838e01612c15565b9a5060208c0135995060408c0135985060608c01359150808211156131a157600080fd5b6131ad8d838e01612b16565b909850965060808c01359150808211156131c657600080fd5b6131d28d838e01612b16565b909650945060a08c01359150808211156131eb57600080fd5b506131f88c828d01612b16565b915080935050809150509295985092959850929598565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561324157600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061326e60408301868861320f565b828103602084015261328181858761320f565b979650505050505050565b60408152600061329f6040830185612f42565b90508260208301529392505050565b6000602082840312156132c057600080fd5b81516129b181613036565b8681526080602082015260006132e560808301878961320f565b82810360408401526132f78187612f6e565b9050828103606084015261147281858761320f565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60408152600061334b60408301858761330c565b9050826020830152949350505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261338857600080fd5b83018035915067ffffffffffffffff8211156133a357600080fd5b6020019150600581901b3603821315612b5b57600080fd5b634e487b7160e01b600052601160045260246000fd5b600060001982036133e4576133e46133bb565b5060010190565b6000808335601e1984360301811261340257600080fd5b830160208101925035905067ffffffffffffffff81111561342257600080fd5b8060051b3603821315612b5b57600080fd5b81835260006020808501808196508560051b810191508460005b8781101561348457828403895261346582886133eb565b61347086828461320f565b9a87019a955050509084019060010161344e565b5091979650505050505050565b6080815260006134a560808301898b61320f565b602083820381850152818883528183019050818960051b8401018a60005b8b8110156134fd57601f198684030184526134de828e6133eb565b6134e985828461320f565b9587019594505050908401906001016134c3565b50508581036040870152885180825283820194509150600582901b81018301838a0160005b8481101561355057601f1984840301875261353e838351612f6e565b96860196925090850190600101613522565b5050868103606088015261356581898b613434565b9e9d5050505050505050505050505050565b6001600160a01b038616815260606020820152600061359a60608301868861320f565b82810360408401526116bc81858761320f565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156135dc57600080fd5b8260051b80838637939093019392505050565b60006135fc8284866135ad565b949350505050565b600067ffffffffffffffff82111561361e5761361e612bce565b5060051b60200190565b600061363b61363684613604565b612be4565b8381529050602080820190600585901b84018681111561365a57600080fd5b845b8181101561369657803567ffffffffffffffff81111561367c5760008081fd5b61368889828901612c15565b85525092820192820161365c565b505050509392505050565b60006129b1368484613628565b6000808335601e198436030181126136c557600080fd5b83018035915067ffffffffffffffff8211156136e057600080fd5b602001915036819003821315612b5b57600080fd5b6001600160a01b038616815284602082015283604082015260806060820152600061328160808301848661330c565b6001600160a01b0387168152600060206080818401526137476080840189612f6e565b838103604085015261375a81888a61320f565b84810360608601528581529050818101600586901b820183018760005b888110156137e657601f198584030184528135601e198b360301811261379c57600080fd5b8a01868101903567ffffffffffffffff8111156137b857600080fd5b8036038213156137c757600080fd5b6137d285828461330c565b958801959450505090850190600101613777565b50909c9b505050505050505050505050565b600061380661363684613604565b83815260208082019190600586811b86013681111561382457600080fd5b865b818110156138b157803567ffffffffffffffff8111156138465760008081fd5b880136601f8201126138585760008081fd5b803561386661363682613604565b81815290851b820186019086810190368311156138835760008081fd5b928701925b828410156138a157833582529287019290870190613888565b8952505050948301948301613826565b5092979650505050505050565b60006138cc61363684613604565b80848252602080830192508560051b8501368111156138ea57600080fd5b855b8181101561393a57803567ffffffffffffffff81111561390c5760008081fd5b870136601f82011261391e5760008081fd5b61392c368235868401613628565b8652509382019382016138ec565b50919695505050505050565b600061395461363684613604565b83815260208082019190600586811b86013681111561397257600080fd5b865b818110156138b157803567ffffffffffffffff8111156139945760008081fd5b880136601f8201126139a65760008081fd5b80356139b461363682613604565b81815290851b820186019086810190368311156139d15760008081fd5b928701925b828410156139ef578335825292870192908701906139d6565b8952505050948301948301613974565b600181811c90821680613a1357607f821691505b602082108103613a3357634e487b7160e01b600052602260045260246000fd5b50919050565b60008251613a4b818460208701612f1e565b9190910192915050565b815160009082906020808601845b83811015613a7f57815185529382019390820190600101613a63565b50929695505050505050565b6020815260006135fc60208301848661330c565b600060208284031215613ab157600080fd5b5051919050565b600061ffff808316818103613acf57613acf6133bb565b6001019392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b11816017850160208801612f1e565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613b4e816028840160208801612f1e565b01602801949350505050565b6020815260006129b16020830184612f42565b601f8211156107cf57600081815260208120601f850160051c81016020861015613b945750805b601f850160051c820191505b818110156119e757828155600101613ba0565b815167ffffffffffffffff811115613bcd57613bcd612bce565b613be181613bdb84546139ff565b84613b6d565b602080601f831160018114613c165760008415613bfe5750858301515b600019600386901b1c1916600185901b1785556119e7565b600085815260208120601f198616915b82811015613c4557888601518255948401946001909101908401613c26565b5085821015613c635787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761054d5761054d6133bb565b8082018082111561054d5761054d6133bb565b600081613cac57613cac6133bb565b50600019019056fea2646970667358221220f05ad7d44e260459dfb1e3041191db82c4b254a4059000667067959881cb865f64736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c806384b0196e11610104578063d547741f116100a2578063e63ab1e911610071578063e63ab1e914610432578063e72cbd5314610459578063ecc0382a14610480578063f30553d51461049357600080fd5b8063d547741f146103e7578063d5f2077c146103fa578063da7422281461040c578063e56f2fe41461041f57600080fd5b8063a217fddf116100de578063a217fddf14610383578063b21c2cdc1461038b578063bd2cc82a146103b2578063ce1b815f146103d657600080fd5b806384b0196e1461031c57806391d14854146103375780639d9d91f61461037057600080fd5b80633f4ba83a1161017157806359c191e41161014b57806359c191e4146102d05780635aaa24bf146102f65780635c975abb146103095780638456cb591461031457600080fd5b80633f4ba83a146102a2578063439ff3ce146102aa578063572b6c05146102bd57600080fd5b8063248a9ca3116101ad578063248a9ca3146102245780632f2ff15d1461025557806336568abe146102685780633a2cf31a1461027b57600080fd5b806301ffc9a7146101d45780630c85fbb3146101fc57806310da539314610211575b600080fd5b6101e76101e2366004612ad4565b6104ba565b60405190151581526020015b60405180910390f35b61020f61020a366004612b62565b610553565b005b61020f61021f366004612c85565b6105bb565b610247610232366004612d4d565b60009081526065602052604090206001015490565b6040519081526020016101f3565b61020f610263366004612d82565b6107aa565b61020f610276366004612d82565b6107d4565b6102477f1d2951170e2f5d8eb8a7a48a737f5f1680469c14594abd27536867bfb559f88f81565b61020f610870565b61020f6102b8366004612df0565b6108a5565b6101e76102cb366004612ee1565b610bec565b61012f546001600160a01b03165b6040516001600160a01b0390911681526020016101f3565b61020f610304366004612efc565b610c06565b60fd5460ff166101e7565b61020f610c6f565b610324610ca1565b6040516101f39796959493929190612fa9565b6101e7610345366004612d82565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61020f61037e366004613044565b610d63565b610247600081565b6102477f45cf7a9b20b47d492887b813085b48aa1988f1f482fe79948578452b4b4cbedd81565b6101e76103c0366004612d4d565b6000908152610132602052604090205460ff1690565b6097546001600160a01b03166102de565b61020f6103f5366004612d82565b610d95565b610130546001600160a01b03166102de565b61020f61041a366004612ee1565b610dba565b61020f61042d36600461307b565b610e24565b6102477f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6101e7610467366004613120565b60ff908116600090815261013360205260409020541690565b61020f61048e36600461313b565b610fba565b6102477f30ed1d13f34eab3b4d1a3291d48db1d77bbc98ec9480b9131e4360220fd46fb081565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061054d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61055b61120f565b61056784848484611264565b61056f611381565b6001600160a01b03167f25601c42b4517e81abacb7c77cd6d6697ea55465121e953721d60becc43b88e2858585856040516105ad949392919061325a565b60405180910390a250505050565b6105c361120f565b8483146106175760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20312d4172726179206d69736d6174636800000060448201526064015b60405180910390fd5b8481146106665760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20322d4172726179206d69736d61746368000000604482015260640161060e565b610130546001600160a01b0316636b40634189610690610684611381565b8b8b8b8b8b8b8b611390565b6040518363ffffffff1660e01b81526004016106ad92919061328c565b602060405180830381865afa1580156106ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ee91906132ae565b61073a5760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a20496e76616c6964207369676e61747572650000604482015260640161060e565b600061074b8886868a8a888861147f565b9050610755611381565b6001600160a01b03167fd19ae26d53e6e3446633338937b673d431c042f61b32854f821bc2b2b025b2c4898989858888604051610797969594939291906132cb565b60405180910390a2505050505050505050565b6000828152606560205260409020600101546107c5816116c8565b6107cf83836116d9565b505050565b6107dc611381565b6001600160a01b0316816001600160a01b0316146108625760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161060e565b61086c828261177c565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a61089a816116c8565b6108a261181d565b50565b6108ad61120f565b8685146108fc5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20312d4172726179206d69736d61746368000000604482015260640161060e565b84831461094b5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20322d4172726179206d69736d61746368000000604482015260640161060e565b86811461099a5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20332d4172726179206d69736d61746368000000604482015260640161060e565b610130546001600160a01b0316636b4063418b8b6109c66109b9611381565b8d8d8d8d8d8d8d8d611875565b6040518463ffffffff1660e01b81526004016109e493929190613337565b602060405180830381865afa158015610a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2591906132ae565b610a715760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a20496e76616c6964207369676e61747572650000604482015260640161060e565b60008767ffffffffffffffff811115610a8c57610a8c612bce565b604051908082528060200260200182016040528015610abf57816020015b6060815260200190600190039081610aaa5790505b50905060005b88811015610b8a57610b5a8a8a83818110610ae257610ae261335b565b90506020020135878784818110610afb57610afb61335b565b9050602002810190610b0d9190613371565b8b8b86818110610b1f57610b1f61335b565b9050602002810190610b319190613371565b898988818110610b4357610b4361335b565b9050602002810190610b559190613371565b61147f565b828281518110610b6c57610b6c61335b565b60200260200101819052508080610b82906133d1565b915050610ac5565b50610b93611381565b6001600160a01b03167f9327e7d8f5446a92ddcaf7ccd64ad67693773944fe2db95200e2d4db200543598a8a8a8a868989604051610bd79796959493929190613491565b60405180910390a25050505050505050505050565b600061054d826097546001600160a01b0391821691161490565b610c0e61120f565b610c188282611948565b610c20611381565b6001600160a01b03167f529140d9ae57da9c5515c8fe288c3865d4cbb81cb143062f99a466cb4bb6fa958383604051610c63929190918252602082015260400190565b60405180910390a25050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c99816116c8565b6108a26119ef565b60006060806000806000606060c9546000801b148015610cc1575060ca54155b610d0d5760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a65640000000000000000000000604482015260640161060e565b610d15611a2d565b610d1d611abf565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b6000610d6e816116c8565b5060ff91909116600090815261013360205260409020805460ff1916911515919091179055565b600082815260656020526040902060010154610db0816116c8565b6107cf838361177c565b6000610dc5816116c8565b6001600160a01b038216610e1b5760405162461bcd60e51b815260206004820152601960248201527f417373657452657665616c3a205a65726f206164647265737300000000000000604482015260640161060e565b61086c82611ace565b600054610100900460ff1615808015610e445750600054600160ff909116105b80610e5e5750303b158015610e5e575060005460ff166001145b610ed05760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060e565b6000805460ff191660011790558015610ef3576000805461ff0019166101001790555b61012f80546001600160a01b038088167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255610130805492871692909116919091179055610f4683611bd2565b610f508787611c46565b610f58611cbb565b610f60611d26565b610f6b6000836116d9565b8015610fb1576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b610fc261120f565b8483146110115760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20312d4172726179206d69736d61746368000000604482015260640161060e565b8481146110605760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20322d4172726179206d69736d61746368000000604482015260640161060e565b600061106f8960a01c60ff1690565b60ff80821660009081526101336020526040902054919250166110d45760405162461bcd60e51b815260206004820152601860248201527f417373657452657665616c3a204e6f7420616c6c6f7765640000000000000000604482015260640161060e565b610130546001600160a01b0316636b4063418b6110fe6110f2611381565b8d8c8c8c8c8c8c611d99565b6040518363ffffffff1660e01b815260040161111b92919061328c565b602060405180830381865afa158015611138573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115c91906132ae565b6111a85760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a20496e76616c6964207369676e61747572650000604482015260640161060e565b6111b28989611948565b60006111c38a87878b8b898961147f565b90506111cd611381565b6001600160a01b03167fd19ae26d53e6e3446633338937b673d431c042f61b32854f821bc2b2b025b2c48b8a8a858989604051610bd7969594939291906132cb565b60fd5460ff16156112625760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161060e565b565b8281146112b35760405162461bcd60e51b815260206004820152601a60248201527f417373657452657665616c3a20496e76616c696420696e707574000000000000604482015260640161060e565b60005b8381101561130a576112f88585838181106112d3576112d361335b565b905060200201358484848181106112ec576112ec61335b565b90506020020135611dd4565b80611302816133d1565b9150506112b6565b5061012f546001600160a01b03166320820ec3611325611381565b868686866040518663ffffffff1660e01b8152600401611349959493929190613577565b600060405180830381600087803b15801561136357600080fd5b505af1158015611377573d6000803e3d6000fd5b5050505050505050565b600061138b611e83565b905090565b60006114727f1d2951170e2f5d8eb8a7a48a737f5f1680469c14594abd27536867bfb559f88f8a8a8a8a6040516020016113cb9291906135ef565b60408051601f1981840301815291905280516020909101206113f56113f08a8c6136a1565b611e8d565b88886040516020016114089291906135ef565b60408051601f198184030181528282528051602091820120908301979097526001600160a01b03909516948101949094526060840192909252608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120611f81565b9998505050505050505050565b6060600061148e88888b611fc9565b905060005b838110156115745761013260008686848181106114b2576114b261335b565b602090810292909201358352508101919091526040016000205460ff161561151c5760405162461bcd60e51b815260206004820152601e60248201527f417373657452657665616c3a204861736820616c726561647920757365640000604482015260640161060e565b600161013260008787858181106115355761153561335b565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550808061156c906133d1565b915050611493565b5080516001036116495761012f546001600160a01b031663bb7fde71611598611381565b836000815181106115ab576115ab61335b565b6020026020010151898960008181106115c6576115c661335b565b905060200201358c8c60008181106115e0576115e061335b565b90506020028101906115f291906136ae565b6040518663ffffffff1660e01b81526004016116129594939291906136f5565b600060405180830381600087803b15801561162c57600080fd5b505af1158015611640573d6000803e3d6000fd5b505050506116bc565b61012f546001600160a01b031663a55784ef611663611381565b8389898d8d6040518763ffffffff1660e01b815260040161168996959493929190613724565b600060405180830381600087803b1580156116a357600080fd5b505af11580156116b7573d6000803e3d6000fd5b505050505b98975050505050505050565b6108a2816116d4611381565b6121cc565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff1661086c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611738611381565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff161561086c5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191690556117d9611381565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b611825612241565b60fd805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611858611381565b6040516001600160a01b03909116815260200160405180910390a1565b600061193a7f30ed1d13f34eab3b4d1a3291d48db1d77bbc98ec9480b9131e4360220fd46fb08b8b8b6040516020016118af9291906135ef565b60408051601f1981840301815291905280516020909101206118d96118d48b8d6137f8565b612293565b6118eb6118e68a8c6138be565b612357565b6118fd6118f8898b613946565b6123fd565b6040805160208101979097526001600160a01b03909516948601949094526060850192909252608084015260a083015260c082015260e001611457565b9a9950505050505050505050565b6119528282611dd4565b61012f546001600160a01b031663124d91e561196c611381565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024810185905260448101849052606401600060405180830381600087803b1580156119d357600080fd5b505af11580156119e7573d6000803e3d6000fd5b505050505050565b6119f761120f565b60fd805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611858611381565b606060cb8054611a3c906139ff565b80601f0160208091040260200160405190810160405280929190818152602001828054611a68906139ff565b8015611ab55780601f10611a8a57610100808354040283529160200191611ab5565b820191906000526020600020905b815481529060010190602001808311611a9857829003601f168201915b5050505050905090565b606060cc8054611a3c906139ff565b6097546001600160a01b0390811690821603611b525760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c72656164792073657400000000000000000000000000000000606482015260840161060e565b611b5a611381565b6097546040516001600160a01b03928316928481169216907f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e590600090a4609780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b600054610100900460ff16611c3d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b6108a2816124c1565b600054610100900460ff16611cb15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b61086c8282612535565b600054610100900460ff166112625760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b600054610100900460ff16611d915760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b6112626125c8565b60006114727f45cf7a9b20b47d492887b813085b48aa1988f1f482fe79948578452b4b4cbedd8a8a8a8a6040516020016113cb9291906135ef565b6000611ddf8361263f565b90508060a0015115611e335760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20416c72656164792072657665616c6564000000604482015260640161060e565b600082116107cf5760405162461bcd60e51b815260206004820152601b60248201527f417373657452657665616c3a20496e76616c696420616d6f756e740000000000604482015260640161060e565b600061138b6126cc565b600080825167ffffffffffffffff811115611eaa57611eaa612bce565b604051908082528060200260200182016040528015611ed3578160200160208202803683370190505b50905060005b8351811015611f5157838181518110611ef457611ef461335b565b6020026020010151604051602001611f0c9190613a39565b60405160208183030381529060405280519060200120828281518110611f3457611f3461335b565b602090810291909101015280611f49816133d1565b915050611ed9565b5080604051602001611f639190613a55565b60405160208183030381529060405280519060200120915050919050565b600061054d611f8e61271f565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b60606000611fd68361263f565b90508060a001511561202a5760405162461bcd60e51b815260206004820152601d60248201527f417373657452657665616c3a20416c72656164792072657665616c6564000000604482015260640161060e565b60008467ffffffffffffffff81111561204557612045612bce565b60405190808252806020026020018201604052801561206e578160200160208202803683370190505b50905060005b858110156121c25761012f546000906001600160a01b031663fdda1d0e8989858181106120a3576120a361335b565b90506020028101906120b591906136ae565b6040518363ffffffff1660e01b81526004016120d2929190613a8b565b602060405180830381865afa1580156120ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121139190613a9f565b905080600003612191576020808501516001600160a01b0316600090815261013182526040808220898352909252908120805482906121559061ffff16613ab8565b91906101000a81548161ffff021916908361ffff1602179055905061218d856020015186606001518760800151848960e00151612729565b9150505b808383815181106121a4576121a461335b565b602090810291909101015250806121ba816133d1565b915050612074565b5095945050505050565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff1661086c576121ff81612776565b61220a836020612788565b60405160200161221b929190613ad9565b60408051601f198184030181529082905262461bcd60e51b825261060e91600401613b5a565b60fd5460ff166112625760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161060e565b600080825167ffffffffffffffff8111156122b0576122b0612bce565b6040519080825280602002602001820160405280156122d9578160200160208202803683370190505b50905060005b8351811015611f51578381815181106122fa576122fa61335b565b60200260200101516040516020016123129190613a55565b6040516020818303038152906040528051906020012082828151811061233a5761233a61335b565b60209081029190910101528061234f816133d1565b9150506122df565b600080825167ffffffffffffffff81111561237457612374612bce565b60405190808252806020026020018201604052801561239d578160200160208202803683370190505b50905060005b8351811015611f51576123ce8482815181106123c1576123c161335b565b6020026020010151611e8d565b8282815181106123e0576123e061335b565b6020908102919091010152806123f5816133d1565b9150506123a3565b600080825167ffffffffffffffff81111561241a5761241a612bce565b604051908082528060200260200182016040528015612443578160200160208202803683370190505b50905060005b8351811015611f51578381815181106124645761246461335b565b602002602001015160405160200161247c9190613a55565b604051602081830303815290604052805190602001208282815181106124a4576124a461335b565b6020908102919091010152806124b9816133d1565b915050612449565b600054610100900460ff1661252c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b6108a281611ace565b600054610100900460ff166125a05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b60cb6125ac8382613bb3565b5060cc6125b98282613bb3565b5050600060c981905560ca5550565b600054610100900460ff166126335760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161060e565b60fd805460ff19169055565b604080516101008101825260008082529181018290526080810182905260a0808201839052606060c0830181905260e08301939093526001600160a01b038416602083015283901c60ff169181019190915261269a826129b8565b151560a08201526126af8260a81c61ffff1690565b61ffff16608082015260c89190911c60019081161460e082015290565b6097546000906001600160a01b0316331480156126ea575060143610155b1561271a57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b600061138b6129d6565b60008560c88361273a57600061273d565b60015b60ff16901b60b88561ffff16901b60a88761ffff16901b60a08960ff16901b846001600160a01b03161717171791505095945050505050565b606061054d6001600160a01b03831660145b60606000612797836002613c73565b6127a2906002613c8a565b67ffffffffffffffff8111156127ba576127ba612bce565b6040519080825280601f01601f1916602001820160405280156127e4576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061281b5761281b61335b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061287e5761287e61335b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006128ba846002613c73565b6128c5906001613c8a565b90505b6001811115612962577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106129065761290661335b565b1a60f81b82828151811061291c5761291c61335b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361295b81613c9d565b90506128c8565b5083156129b15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161060e565b9392505050565b6000806129c98360b81c61ffff1690565b61ffff1615159392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f612a01612a4a565b612a09612aa3565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b600080612a55611a2d565b805190915015612a6c578051602090910120919050565b60c9548015612a7b5792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b600080612aae611abf565b805190915015612ac5578051602090910120919050565b60ca548015612a7b5792915050565b600060208284031215612ae657600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146129b157600080fd5b60008083601f840112612b2857600080fd5b50813567ffffffffffffffff811115612b4057600080fd5b6020830191508360208260051b8501011115612b5b57600080fd5b9250929050565b60008060008060408587031215612b7857600080fd5b843567ffffffffffffffff80821115612b9057600080fd5b612b9c88838901612b16565b90965094506020870135915080821115612bb557600080fd5b50612bc287828801612b16565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612c0d57612c0d612bce565b604052919050565b600082601f830112612c2657600080fd5b813567ffffffffffffffff811115612c4057612c40612bce565b612c536020601f19601f84011601612be4565b818152846020838601011115612c6857600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060008060a0898b031215612ca157600080fd5b883567ffffffffffffffff80821115612cb957600080fd5b612cc58c838d01612c15565b995060208b0135985060408b0135915080821115612ce257600080fd5b612cee8c838d01612b16565b909850965060608b0135915080821115612d0757600080fd5b612d138c838d01612b16565b909650945060808b0135915080821115612d2c57600080fd5b50612d398b828c01612b16565b999c989b5096995094979396929594505050565b600060208284031215612d5f57600080fd5b5035919050565b80356001600160a01b0381168114612d7d57600080fd5b919050565b60008060408385031215612d9557600080fd5b82359150612da560208401612d66565b90509250929050565b60008083601f840112612dc057600080fd5b50813567ffffffffffffffff811115612dd857600080fd5b602083019150836020828501011115612b5b57600080fd5b60008060008060008060008060008060a08b8d031215612e0f57600080fd5b8a3567ffffffffffffffff80821115612e2757600080fd5b612e338e838f01612dae565b909c509a5060208d0135915080821115612e4c57600080fd5b612e588e838f01612b16565b909a50985060408d0135915080821115612e7157600080fd5b612e7d8e838f01612b16565b909850965060608d0135915080821115612e9657600080fd5b612ea28e838f01612b16565b909650945060808d0135915080821115612ebb57600080fd5b50612ec88d828e01612b16565b915080935050809150509295989b9194979a5092959850565b600060208284031215612ef357600080fd5b6129b182612d66565b60008060408385031215612f0f57600080fd5b50508035926020909101359150565b60005b83811015612f39578181015183820152602001612f21565b50506000910152565b60008151808452612f5a816020860160208601612f1e565b601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b83811015612f9e57815187529582019590820190600101612f82565b509495945050505050565b7fff000000000000000000000000000000000000000000000000000000000000008816815260e060208201526000612fe460e0830189612f42565b8281036040840152612ff68189612f42565b90508660608401526001600160a01b03861660808401528460a084015282810360c084015261193a8185612f6e565b803560ff81168114612d7d57600080fd5b80151581146108a257600080fd5b6000806040838503121561305757600080fd5b61306083613025565b9150602083013561307081613036565b809150509250929050565b60008060008060008060c0878903121561309457600080fd5b863567ffffffffffffffff808211156130ac57600080fd5b6130b88a838b01612c15565b975060208901359150808211156130ce57600080fd5b506130db89828a01612c15565b9550506130ea60408801612d66565b93506130f860608801612d66565b925061310660808801612d66565b915061311460a08801612d66565b90509295509295509295565b60006020828403121561313257600080fd5b6129b182613025565b600080600080600080600080600060c08a8c03121561315957600080fd5b893567ffffffffffffffff8082111561317157600080fd5b61317d8d838e01612c15565b9a5060208c0135995060408c0135985060608c01359150808211156131a157600080fd5b6131ad8d838e01612b16565b909850965060808c01359150808211156131c657600080fd5b6131d28d838e01612b16565b909650945060a08c01359150808211156131eb57600080fd5b506131f88c828d01612b16565b915080935050809150509295985092959850929598565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561324157600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061326e60408301868861320f565b828103602084015261328181858761320f565b979650505050505050565b60408152600061329f6040830185612f42565b90508260208301529392505050565b6000602082840312156132c057600080fd5b81516129b181613036565b8681526080602082015260006132e560808301878961320f565b82810360408401526132f78187612f6e565b9050828103606084015261147281858761320f565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60408152600061334b60408301858761330c565b9050826020830152949350505050565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261338857600080fd5b83018035915067ffffffffffffffff8211156133a357600080fd5b6020019150600581901b3603821315612b5b57600080fd5b634e487b7160e01b600052601160045260246000fd5b600060001982036133e4576133e46133bb565b5060010190565b6000808335601e1984360301811261340257600080fd5b830160208101925035905067ffffffffffffffff81111561342257600080fd5b8060051b3603821315612b5b57600080fd5b81835260006020808501808196508560051b810191508460005b8781101561348457828403895261346582886133eb565b61347086828461320f565b9a87019a955050509084019060010161344e565b5091979650505050505050565b6080815260006134a560808301898b61320f565b602083820381850152818883528183019050818960051b8401018a60005b8b8110156134fd57601f198684030184526134de828e6133eb565b6134e985828461320f565b9587019594505050908401906001016134c3565b50508581036040870152885180825283820194509150600582901b81018301838a0160005b8481101561355057601f1984840301875261353e838351612f6e565b96860196925090850190600101613522565b5050868103606088015261356581898b613434565b9e9d5050505050505050505050505050565b6001600160a01b038616815260606020820152600061359a60608301868861320f565b82810360408401526116bc81858761320f565b60007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156135dc57600080fd5b8260051b80838637939093019392505050565b60006135fc8284866135ad565b949350505050565b600067ffffffffffffffff82111561361e5761361e612bce565b5060051b60200190565b600061363b61363684613604565b612be4565b8381529050602080820190600585901b84018681111561365a57600080fd5b845b8181101561369657803567ffffffffffffffff81111561367c5760008081fd5b61368889828901612c15565b85525092820192820161365c565b505050509392505050565b60006129b1368484613628565b6000808335601e198436030181126136c557600080fd5b83018035915067ffffffffffffffff8211156136e057600080fd5b602001915036819003821315612b5b57600080fd5b6001600160a01b038616815284602082015283604082015260806060820152600061328160808301848661330c565b6001600160a01b0387168152600060206080818401526137476080840189612f6e565b838103604085015261375a81888a61320f565b84810360608601528581529050818101600586901b820183018760005b888110156137e657601f198584030184528135601e198b360301811261379c57600080fd5b8a01868101903567ffffffffffffffff8111156137b857600080fd5b8036038213156137c757600080fd5b6137d285828461330c565b958801959450505090850190600101613777565b50909c9b505050505050505050505050565b600061380661363684613604565b83815260208082019190600586811b86013681111561382457600080fd5b865b818110156138b157803567ffffffffffffffff8111156138465760008081fd5b880136601f8201126138585760008081fd5b803561386661363682613604565b81815290851b820186019086810190368311156138835760008081fd5b928701925b828410156138a157833582529287019290870190613888565b8952505050948301948301613826565b5092979650505050505050565b60006138cc61363684613604565b80848252602080830192508560051b8501368111156138ea57600080fd5b855b8181101561393a57803567ffffffffffffffff81111561390c5760008081fd5b870136601f82011261391e5760008081fd5b61392c368235868401613628565b8652509382019382016138ec565b50919695505050505050565b600061395461363684613604565b83815260208082019190600586811b86013681111561397257600080fd5b865b818110156138b157803567ffffffffffffffff8111156139945760008081fd5b880136601f8201126139a65760008081fd5b80356139b461363682613604565b81815290851b820186019086810190368311156139d15760008081fd5b928701925b828410156139ef578335825292870192908701906139d6565b8952505050948301948301613974565b600181811c90821680613a1357607f821691505b602082108103613a3357634e487b7160e01b600052602260045260246000fd5b50919050565b60008251613a4b818460208701612f1e565b9190910192915050565b815160009082906020808601845b83811015613a7f57815185529382019390820190600101613a63565b50929695505050505050565b6020815260006135fc60208301848661330c565b600060208284031215613ab157600080fd5b5051919050565b600061ffff808316818103613acf57613acf6133bb565b6001019392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b11816017850160208801612f1e565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613b4e816028840160208801612f1e565b01602801949350505050565b6020815260006129b16020830184612f42565b601f8211156107cf57600081815260208120601f850160051c81016020861015613b945750805b601f850160051c820191505b818110156119e757828155600101613ba0565b815167ffffffffffffffff811115613bcd57613bcd612bce565b613be181613bdb84546139ff565b84613b6d565b602080601f831160018114613c165760008415613bfe5750858301515b600019600386901b1c1916600185901b1785556119e7565b600085815260208120601f198616915b82811015613c4557888601518255948401946001909101908401613c26565b5085821015613c635787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b808202811582820484141761054d5761054d6133bb565b8082018082111561054d5761054d6133bb565b600081613cac57613cac6133bb565b50600019019056fea2646970667358221220f05ad7d44e260459dfb1e3041191db82c4b254a4059000667067959881cb865f64736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "events": { + "EIP712DomainChanged()": { + "details": "MAY be emitted to signal that the domain could have changed." + }, + "Initialized(uint8)": { + "details": "Triggered when the contract has been initialized or reinitialized." + }, + "Paused(address)": { + "details": "Emitted when the pause is triggered by `account`." + }, + "RoleAdminChanged(bytes32,bytes32,bytes32)": { + "details": "Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._" + }, + "RoleGranted(bytes32,address,address)": { + "details": "Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}." + }, + "RoleRevoked(bytes32,address,address)": { + "details": "Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)" + }, + "TrustedForwarderSet(address,address,address)": { + "params": { + "newTrustedForwarder": "new trusted forwarder", + "oldTrustedForwarder": "old trusted forwarder", + "operator": "the sender of the transaction" + } + }, + "Unpaused(address)": { + "details": "Emitted when the pause is lifted by `account`." + } + }, + "kind": "dev", + "methods": { + "burnAndReveal(bytes,uint256,uint256,uint256[],string[],bytes32[])": { + "details": "Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements", + "params": { + "amounts": "The amount of assets to reveal (sum must be equal to the burnAmount)", + "burnAmount": "The amount of assets to burn", + "metadataHashes": "The array of hashes for asset metadata", + "prevTokenId": "The tokenId of the unrevealed asset", + "revealHashes": "A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId", + "signature": "Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer" + } + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "eip712Domain()": { + "details": "See {EIP-5267}. _Available since v4.9._" + }, + "getAssetContract()": { + "returns": { + "assetContractAddres": "The asset contract address" + } + }, + "getAuthValidator()": { + "returns": { + "authValidatorContractAddress": "The auth validator address" + } + }, + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getTierInstantRevealAllowed(uint8)": { + "params": { + "tier": "The tier to check" + }, + "returns": { + "instantRevealAllowed": "Boolean representing whether instant reveal is allowed for the given tier" + } + }, + "getTrustedForwarder()": { + "returns": { + "_0": "return the address of the trusted forwarder" + } + }, + "grantRole(bytes32,address)": { + "details": "Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event." + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "initialize(string,string,address,address,address,address)": { + "params": { + "_assetContract": "The address of the asset contract", + "_authValidator": "The address of the AuthSuperValidator contract", + "_forwarder": "The address of the forwarder contract" + } + }, + "isTrustedForwarder(address)": { + "params": { + "forwarder": "trusted forwarder address to check" + }, + "returns": { + "_0": "true if the address is the same as the trusted forwarder" + } + }, + "paused()": { + "details": "Returns true if the contract is paused, and false otherwise." + }, + "renounceRole(bytes32,address)": { + "details": "Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event." + }, + "revealBatchBurn(uint256[],uint256[])": { + "details": "Can be used to burn multiple copies of the same token id, each copy will be revealed separately", + "params": { + "amounts": "the amounts of the assets to burn", + "tokenIds": "the tokenIds of the assets to burn" + } + }, + "revealBatchMint(bytes,uint256[],uint256[][],string[][],bytes32[][])": { + "details": "Can be used to reveal multiple copies of the same token id", + "params": { + "amounts": "The amount of assets to reveal (must be equal to the length of revealHashes)", + "metadataHashes": "The array of hashes for asset metadata", + "prevTokenIds": "The tokenId of the unrevealed asset", + "revealHashes": "Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId", + "signature": "Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer" + } + }, + "revealBurn(uint256,uint256)": { + "details": "the reveal mechanism works through burning the asset and minting a new one with updated tokenId", + "params": { + "amount": "the amount of tokens to reveal", + "tokenId": "the tokenId of id idasset to reveal" + } + }, + "revealHashUsed(bytes32)": { + "returns": { + "hashUsed": "Boolean representing whether the hash has been used" + } + }, + "revealMint(bytes,uint256,uint256[],string[],bytes32[])": { + "details": "Can be used to reveal multiple copies of the same token id", + "params": { + "amounts": "The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)", + "metadataHashes": "The array of hashes for revealed asset metadata", + "prevTokenId": "The tokenId of the unrevealed asset", + "revealHashes": "A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId", + "signature": "Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer" + } + }, + "revokeRole(bytes32,address)": { + "details": "Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event." + }, + "setTierInstantRevealAllowed(uint8,bool)": { + "params": { + "allowed": "allow or disallow instant reveal for the given tier", + "tier": "the tier to set the permission for" + } + }, + "setTrustedForwarder(address)": { + "details": "Change the address of the trusted forwarder for meta-TX", + "params": { + "trustedForwarder": "The new trustedForwarder" + } + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + } + }, + "title": "AssetReveal", + "version": 1 + }, + "userdoc": { + "events": { + "TrustedForwarderSet(address,address,address)": { + "notice": "Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`" + } + }, + "kind": "user", + "methods": { + "burnAndReveal(bytes,uint256,uint256,uint256[],string[],bytes32[])": { + "notice": "Reveal assets to view their abilities and enhancements and mint them in a single transaction" + }, + "getAssetContract()": { + "notice": "Get the asset contract address" + }, + "getAuthValidator()": { + "notice": "Get the auth validator address" + }, + "getTierInstantRevealAllowed(uint8)": { + "notice": "Get permission for instant reveal for a given tier" + }, + "getTrustedForwarder()": { + "notice": "return the address of the trusted forwarder" + }, + "initialize(string,string,address,address,address,address)": { + "notice": "Initialize the contract" + }, + "isTrustedForwarder(address)": { + "notice": "return true if the forwarder is the trusted forwarder" + }, + "pause()": { + "notice": "Pause the contracts mint and burn functions" + }, + "revealBatchBurn(uint256[],uint256[])": { + "notice": "Burn multiple assets to be able to reveal them later" + }, + "revealBatchMint(bytes,uint256[],uint256[][],string[][],bytes32[][])": { + "notice": "Mint multiple assets with revealed abilities and enhancements" + }, + "revealBurn(uint256,uint256)": { + "notice": "Reveal an asset to view its abilities and enhancements" + }, + "revealHashUsed(bytes32)": { + "notice": "Get the status of a revealHash" + }, + "revealMint(bytes,uint256,uint256[],string[],bytes32[])": { + "notice": "Reveal assets to view their abilities and enhancements" + }, + "setTierInstantRevealAllowed(uint8,bool)": { + "notice": "Set permission for instant reveal for a given tier" + }, + "setTrustedForwarder(address)": { + "notice": "Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only" + }, + "unpause()": { + "notice": "Unpause the contracts mint and burn functions" + } + }, + "notice": "Contract for burning and revealing assets", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 502, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 505, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 2965, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 3888, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 82, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_roles", + "offset": 0, + "slot": "101", + "type": "t_mapping(t_bytes32,t_struct(RoleData)77_storage)" + }, + { + "astId": 377, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 11744, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_trustedForwarder", + "offset": 0, + "slot": "151", + "type": "t_address" + }, + { + "astId": 11855, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "__gap", + "offset": 0, + "slot": "152", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 3579, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_hashedName", + "offset": 0, + "slot": "201", + "type": "t_bytes32" + }, + { + "astId": 3582, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_hashedVersion", + "offset": 0, + "slot": "202", + "type": "t_bytes32" + }, + { + "astId": 3584, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_name", + "offset": 0, + "slot": "203", + "type": "t_string_storage" + }, + { + "astId": 3586, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_version", + "offset": 0, + "slot": "204", + "type": "t_string_storage" + }, + { + "astId": 3844, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "__gap", + "offset": 0, + "slot": "205", + "type": "t_array(t_uint256)48_storage" + }, + { + "astId": 685, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "_paused", + "offset": 0, + "slot": "253", + "type": "t_bool" + }, + { + "astId": 790, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "__gap", + "offset": 0, + "slot": "254", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 8421, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "assetContract", + "offset": 0, + "slot": "303", + "type": "t_contract(IAsset)10610" + }, + { + "astId": 8424, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "authValidator", + "offset": 0, + "slot": "304", + "type": "t_contract(AuthSuperValidator)9788" + }, + { + "astId": 8430, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "revealIds", + "offset": 0, + "slot": "305", + "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint16))" + }, + { + "astId": 8434, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "revealHashesUsed", + "offset": 0, + "slot": "306", + "type": "t_mapping(t_bytes32,t_bool)" + }, + { + "astId": 8438, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "tierInstantRevealAllowed", + "offset": 0, + "slot": "307", + "type": "t_mapping(t_uint8,t_bool)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)48_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[48]", + "numberOfBytes": "1536" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(AuthSuperValidator)9788": { + "encoding": "inplace", + "label": "contract AuthSuperValidator", + "numberOfBytes": "20" + }, + "t_contract(IAsset)10610": { + "encoding": "inplace", + "label": "contract IAsset", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_uint256,t_uint16))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(uint256 => uint16))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_uint16)" + }, + "t_mapping(t_bytes32,t_bool)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_bytes32,t_struct(RoleData)77_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)77_storage" + }, + "t_mapping(t_uint256,t_uint16)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint16)", + "numberOfBytes": "32", + "value": "t_uint16" + }, + "t_mapping(t_uint8,t_bool)": { + "encoding": "mapping", + "key": "t_uint8", + "label": "mapping(uint8 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(RoleData)77_storage": { + "encoding": "inplace", + "label": "struct AccessControlUpgradeable.RoleData", + "members": [ + { + "astId": 74, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 76, + "contract": "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol:AssetReveal", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_uint16": { + "encoding": "inplace", + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/AssetReveal_Proxy.json b/packages/deploy/deployments/mumbai/AssetReveal_Proxy.json new file mode 100644 index 0000000000..47a2afc9d0 --- /dev/null +++ b/packages/deploy/deployments/mumbai/AssetReveal_Proxy.json @@ -0,0 +1,292 @@ +{ + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "transactionIndex": 1, + "gasUsed": "897468", + "logsBloom": "0x00000084000000000000000000000000400000000000000000000080000000000002000000008400000000000001000000008000000000000000000000000000000000000000000000000000000002800000000000000000000100000000004000000000020000000020020000000800000000800000000080000000000000000000010040000020000000000000000000000000000080000000000000a00000200000000000000000000000001400000000000000000000001000000000004000000020000000000001000000040000000000000420000100108040000020002000000000000000000000000000000004000000000000000000000000100200", + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b", + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000006a2b6427d56495a0e49fc4d1c3bb3ac32c2d5e0d" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 6, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 7, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 8, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x5Fd26501cB11Ac4b60F3c62068E6155270E89f28", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 9, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + }, + { + "transactionIndex": 1, + "blockNumber": 40238295, + "transactionHash": "0xdd9319e897182cbced39533b596b8f76fa99d3bc78fe6528a67fd52e3ff679d0", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x0000000000000000000000000000000000000000000000000007f89b2157dc0000000000000000000000000000000000000000000000000fbf907844003fb6e4000000000000000000000000000000000000000000003472b012f4a25ee5a15900000000000000000000000000000000000000000000000fbf887fa8dee7dae4000000000000000000000000000000000000000000003472b01aed3d803d7d59", + "logIndex": 10, + "blockHash": "0x57b7e669bbc3270823a23f919ecaff9f17f878d3f668e6c7c9cbbb91009e1b5b" + } + ], + "blockNumber": 40238295, + "cumulativeGasUsed": "1118752", + "status": 1, + "byzantium": true + }, + "args": [ + "0x6a2B6427d56495A0e49Fc4D1C3Bb3ac32C2d5E0D", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xe56f2fe400000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000178fd5dec6477364d1beba000e07c18b7be6164500000000000000000000000012467f6e7b23347abe0109968a9886a6c408d25a00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f700000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165000000000000000000000000000000000000000000000000000000000000001453616e64626f782041737365742052657665616c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000003312e300000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/Asset_Implementation.json b/packages/deploy/deployments/mumbai/Asset_Implementation.json new file mode 100644 index 0000000000..96a6dc5539 --- /dev/null +++ b/packages/deploy/deployments/mumbai/Asset_Implementation.json @@ -0,0 +1,2156 @@ +{ + "address": "0xD0D6724D44381c21836cEed6d5DaC14aFAe8f168", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "royaltyBPS", + "type": "uint16" + } + ], + "name": "DefaultRoyaltyBpsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "DefaultRoyaltyReceiverSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "OperatorFilterRegistrySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_royaltyManager", + "type": "address" + } + ], + "name": "RoyaltyManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "splitter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "RoyaltyRecipientSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "TokenRoyaltyRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "splitterAddress", + "type": "address" + } + ], + "name": "TokenRoyaltySplitterSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MODERATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "burnBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "burnBatchFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllSplits", + "outputs": [ + { + "internalType": "address payable[]", + "name": "splits", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getCreatorAddress", + "outputs": [ + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getCreatorNonce", + "outputs": [ + { + "internalType": "uint16", + "name": "creatorNonce", + "type": "uint16" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getOperatorFilterRegistry", + "outputs": [ + { + "internalType": "contract IOperatorFilterRegistry", + "name": "operatorFilterRegistryAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getRecipients", + "outputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "bps", + "type": "uint16" + } + ], + "internalType": "struct Recipient[]", + "name": "recipients", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getRevealNonce", + "outputs": [ + { + "internalType": "uint16", + "name": "revealNonce", + "type": "uint16" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRoyaltyManager", + "outputs": [ + { + "internalType": "address", + "name": "managerAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getTier", + "outputs": [ + { + "internalType": "uint8", + "name": "tier", + "type": "uint8" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + } + ], + "name": "getTokenIdByMetadataHash", + "outputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getTokenRoyaltiesSplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "splitterAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "name": "hashUsed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "assetAdmin", + "type": "address" + }, + { + "internalType": "string", + "name": "baseUri", + "type": "string" + }, + { + "internalType": "address", + "name": "commonSubscription", + "type": "address" + }, + { + "internalType": "address", + "name": "_manager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isBridged", + "outputs": [ + { + "internalType": "bool", + "name": "bridged", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "isRevealed", + "outputs": [ + { + "internalType": "bool", + "name": "revealed", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "string[]", + "name": "metadataHashes", + "type": "string[]" + } + ], + "name": "mintBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subscriptionOrRegistrantToCopy", + "type": "address" + }, + { + "internalType": "bool", + "name": "subscribe", + "type": "bool" + } + ], + "name": "registerAndSubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "royaltyInfo", + "outputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "royaltyAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "baseURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "setOperatorRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "setTokenRoyalties", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadata", + "type": "string" + } + ], + "name": "setTokenURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "supported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "tokenURI", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xa60229c3b993f7dc862f9d8ae9256658fa6d837c81bc9fcfea34b92771ffb4a6", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0xD0D6724D44381c21836cEed6d5DaC14aFAe8f168", + "transactionIndex": 6, + "gasUsed": "4436820", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000002000000000000000000000000000002000000000000000000000800000000000000000040100000000000000000000000000000000000200000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000200000200000000000000000000000000400000000000000000000000040000000004000000000000000000001000000041000000000000000000000108000000000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x0c54b85bbf15864a33975d902cb6e28f29b628b622be94f99cf6ab3d8fd4baf6", + "transactionHash": "0xa60229c3b993f7dc862f9d8ae9256658fa6d837c81bc9fcfea34b92771ffb4a6", + "logs": [ + { + "transactionIndex": 6, + "blockNumber": 40238280, + "transactionHash": "0xa60229c3b993f7dc862f9d8ae9256658fa6d837c81bc9fcfea34b92771ffb4a6", + "address": "0xD0D6724D44381c21836cEed6d5DaC14aFAe8f168", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 31, + "blockHash": "0x0c54b85bbf15864a33975d902cb6e28f29b628b622be94f99cf6ab3d8fd4baf6" + }, + { + "transactionIndex": 6, + "blockNumber": 40238280, + "transactionHash": "0xa60229c3b993f7dc862f9d8ae9256658fa6d837c81bc9fcfea34b92771ffb4a6", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" + ], + "data": "0x0000000000000000000000000000000000000000000000000017a4e57c0c6c0000000000000000000000000000000000000000000000000fbfdee916d51699c8000000000000000000000000000000000000000000001300a44f47e3c4a4178b00000000000000000000000000000000000000000000000fbfc74431590a2dc8000000000000000000000000000000000000000000001300a466ecc940b0838b", + "logIndex": 32, + "blockHash": "0x0c54b85bbf15864a33975d902cb6e28f29b628b622be94f99cf6ab3d8fd4baf6" + } + ], + "blockNumber": 40238280, + "cumulativeGasUsed": "5168324", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "a7dad225e4948fd90c6be2fd4b947044", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"royaltyBPS\",\"type\":\"uint16\"}],\"name\":\"DefaultRoyaltyBpsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"DefaultRoyaltyReceiverSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"OperatorFilterRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_royaltyManager\",\"type\":\"address\"}],\"name\":\"RoyaltyManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"splitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"RoyaltyRecipientSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"TokenRoyaltyRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"splitterAddress\",\"type\":\"address\"}],\"name\":\"TokenRoyaltySplitterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarderAddress\",\"type\":\"address\"}],\"name\":\"TrustedForwarderChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"TrustedForwarderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BURNER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINTER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MODERATOR_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"burnBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"burnBatchFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"exists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllSplits\",\"outputs\":[{\"internalType\":\"address payable[]\",\"name\":\"splits\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getCreatorAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getCreatorNonce\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"creatorNonce\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOperatorFilterRegistry\",\"outputs\":[{\"internalType\":\"contract IOperatorFilterRegistry\",\"name\":\"operatorFilterRegistryAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getRecipients\",\"outputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"bps\",\"type\":\"uint16\"}],\"internalType\":\"struct Recipient[]\",\"name\":\"recipients\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getRevealNonce\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"revealNonce\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRoyaltyManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"managerAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTier\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"tier\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"metadataHash\",\"type\":\"string\"}],\"name\":\"getTokenIdByMetadataHash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getTokenRoyaltiesSplitter\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"splitterAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTrustedForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"hashUsed\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetAdmin\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"baseUri\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"commonSubscription\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_manager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"isBridged\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"bridged\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"isRevealed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"revealed\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isTrustedForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"metadataHash\",\"type\":\"string\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"metadataHashes\",\"type\":\"string[]\"}],\"name\":\"mintBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriptionOrRegistrantToCopy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"subscribe\",\"type\":\"bool\"}],\"name\":\"registerAndSubscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"royaltyInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"royaltyAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"}],\"name\":\"setBaseURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"setOperatorRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"setTokenRoyalties\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"metadata\",\"type\":\"string\"}],\"name\":\"setTokenURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"trustedForwarder\",\"type\":\"address\"}],\"name\":\"setTrustedForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"supported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"uri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"tokenURI\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"details\":\"This contract is final and should not be inherited\",\"events\":{\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"RoleAdminChanged(bytes32,bytes32,bytes32)\":{\"details\":\"Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._\"},\"RoleGranted(bytes32,address,address)\":{\"details\":\"Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}.\"},\"RoleRevoked(bytes32,address,address)\":{\"details\":\"Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)\"},\"TransferBatch(address,address,address,uint256[],uint256[])\":{\"details\":\"Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all transfers.\"},\"TransferSingle(address,address,address,uint256,uint256)\":{\"details\":\"Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\"},\"TrustedForwarderSet(address,address,address)\":{\"params\":{\"newTrustedForwarder\":\"new trusted forwarder\",\"oldTrustedForwarder\":\"old trusted forwarder\",\"operator\":\"the sender of the transaction\"}},\"URI(string,uint256)\":{\"details\":\"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}.\"}},\"kind\":\"dev\",\"methods\":{\"balanceOf(address,uint256)\":{\"details\":\"See {IERC1155-balanceOf}. Requirements: - `account` cannot be the zero address.\"},\"balanceOfBatch(address[],uint256[])\":{\"details\":\"See {IERC1155-balanceOfBatch}. Requirements: - `accounts` and `ids` must have the same length.\"},\"burnBatchFrom(address,uint256[],uint256[])\":{\"details\":\"Only the minter role can burn tokensThis function was added with token recycling and bridging in mind but may have other use casesThe length of the ids and amounts arrays must be the same\",\"params\":{\"account\":\"The account to burn tokens from\",\"amounts\":\"An array of amounts of tokens to burn\",\"ids\":\"An array of token ids to burn\"}},\"burnFrom(address,uint256,uint256)\":{\"details\":\"Only the minter role can burn tokensThis function was added with token recycling and bridging in mind but may have other use cases\",\"params\":{\"account\":\"The account to burn tokens from\",\"amount\":\"The amount of tokens to burn\",\"id\":\"The token id to burn\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"exists(uint256)\":{\"details\":\"Indicates whether any token exist with a given id, or not.\"},\"getAllSplits()\":{\"returns\":{\"splits\":\"the royalty receiver's array\"}},\"getCreatorAddress(uint256)\":{\"params\":{\"tokenId\":\"The token id to extract the creator address from\"},\"returns\":{\"creator\":\"The asset creator address\"}},\"getCreatorNonce(uint256)\":{\"params\":{\"tokenId\":\"The token id to extract the asset nonce from\"},\"returns\":{\"creatorNonce\":\"The asset creator nonce\"}},\"getOperatorFilterRegistry()\":{\"returns\":{\"operatorFilterRegistryAddress\":\"address of operator filter registry contract.\"}},\"getRecipients(uint256)\":{\"details\":\"returns the default address for tokens with no recipients.\",\"params\":{\"tokenId\":\"is the token id for which the recipient should be returned.\"},\"returns\":{\"recipients\":\"array of royalty recipients for the token\"}},\"getRevealNonce(uint256)\":{\"params\":{\"tokenId\":\"The token id to extract reveal nonce from\"},\"returns\":{\"revealNonce\":\"The reveal nonce of the asset\"}},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoyaltyManager()\":{\"returns\":{\"managerAddress\":\"address of royalty manager.\"}},\"getTier(uint256)\":{\"params\":{\"tokenId\":\"The token id to extract the tier from\"},\"returns\":{\"tier\":\"The asset tier, determined by the catalyst used to create it\"}},\"getTokenIdByMetadataHash(string)\":{\"params\":{\"metadataHash\":\"The metadata hash to get tokenId for\"},\"returns\":{\"tokenId\":\"the tokenId associated with the metadata hash\"}},\"getTokenRoyaltiesSplitter(uint256)\":{\"params\":{\"tokenId\":\"is the token id for which royalty splitter should be returned.\"},\"returns\":{\"splitterAddress\":\"address of royalty splitter for the token\"}},\"getTrustedForwarder()\":{\"returns\":{\"_0\":\"return the address of the trusted forwarder\"}},\"grantRole(bytes32,address)\":{\"details\":\"Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event.\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"initialize(address,address,string,address,address)\":{\"params\":{\"_manager\":\"The address of the royalty manager\",\"assetAdmin\":\"The address of the asset admin\",\"baseUri\":\"The base URI for the token metadata\",\"commonSubscription\":\"The address of the operator filter subscription\",\"forwarder\":\"The address of the trusted forwarder\"}},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC1155-isApprovedForAll}.\"},\"isBridged(uint256)\":{\"params\":{\"tokenId\":\"The token id to extract the bridged flag from\"},\"returns\":{\"bridged\":\"Whether the asset is bridged or not\"}},\"isRevealed(uint256)\":{\"params\":{\"tokenId\":\"The token id to extract the revealed flag from\"},\"returns\":{\"revealed\":\"Whether the asset is revealed or not\"}},\"isTrustedForwarder(address)\":{\"params\":{\"forwarder\":\"trusted forwarder address to check\"},\"returns\":{\"_0\":\"true if the address is the same as the trusted forwarder\"}},\"mint(address,uint256,uint256,string)\":{\"details\":\"Only callable by the minter role\",\"params\":{\"amount\":\"The amount of the token to mint\",\"id\":\"The id of the token to mint\",\"metadataHash\":\"The metadata hash of the token to mint\",\"to\":\"The address of the recipient\"}},\"mintBatch(address,uint256[],uint256[],string[])\":{\"details\":\"Only callable by the minter role\",\"params\":{\"amounts\":\"The amounts of the tokens to mint\",\"ids\":\"The ids of the tokens to mint\",\"metadataHashes\":\"The metadata hashes of the tokens to mint\",\"to\":\"The address of the recipient\"}},\"registerAndSubscribe(address,bool)\":{\"details\":\"used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\",\"params\":{\"subscribe\":\"bool to signify subscription \\\"true\\\"\\\" or to copy the list \\\"false\\\".\",\"subscriptionOrRegistrantToCopy\":\"registration address of the list to subscribe.\"}},\"renounceRole(bytes32,address)\":{\"details\":\"Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event.\"},\"revokeRole(bytes32,address)\":{\"details\":\"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event.\"},\"royaltyInfo(uint256,uint256)\":{\"params\":{\"tokenId\":\"of the token for which the royalty is needed to be distributed\",\"value\":\"the amount on which the royalty is calculated\"},\"returns\":{\"receiver\":\"address the royalty receiver\",\"royaltyAmount\":\"value the EIP2981 royalty\"}},\"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\":{\"details\":\"call data should be optimized to order ids so packedBalance can be used efficiently.\",\"params\":{\"amounts\":\"amount of each token type transfered.\",\"data\":\"additional data accompanying the transfer.\",\"from\":\"address from which tokens are transfered.\",\"ids\":\"ids of each token type transfered.\",\"to\":\"address to which the token will be transfered.\"}},\"safeTransferFrom(address,address,uint256,uint256,bytes)\":{\"params\":{\"amount\":\"amount of token transfered.\",\"data\":\"additional data accompanying the transfer.\",\"from\":\"address from which tokens are transfered.\",\"id\":\"the token type transfered.\",\"to\":\"address to which the token will be transfered.\"}},\"setApprovalForAll(address,bool)\":{\"params\":{\"approved\":\"whether to approve or revoke\",\"operator\":\"address which will be granted rights to transfer all tokens of the caller.\"}},\"setBaseURI(string)\":{\"params\":{\"baseURI\":\"The new base URI\"}},\"setOperatorRegistry(address)\":{\"params\":{\"registry\":\"the address of the registry\"}},\"setTokenRoyalties(uint256,address,address)\":{\"params\":{\"creator\":\"the creator of the tokens.\",\"recipient\":\"the royalty recipient for the splitter of the creator.\",\"tokenId\":\"the id of the token for which the EIP2981 royalty is set for.\"}},\"setTokenURI(uint256,string)\":{\"details\":\"The metadata hash should be the IPFS CIDv1 base32 encoded hash\",\"params\":{\"metadata\":\"The new URI for asset's metadata\",\"tokenId\":\"The token id to set URI for\"}},\"setTrustedForwarder(address)\":{\"details\":\"Change the address of the trusted forwarder for meta-TX\",\"params\":{\"trustedForwarder\":\"The new trustedForwarder\"}},\"supportsInterface(bytes4)\":{\"params\":{\"id\":\"the interface identifier, as specified in ERC-165.\"},\"returns\":{\"supported\":\"`true` if the contract implements `id`.\"}},\"totalSupply(uint256)\":{\"details\":\"Total amount of tokens in with a given id.\"},\"uri(uint256)\":{\"params\":{\"tokenId\":\"The token id to get URI for\"},\"returns\":{\"tokenURI\":\"the URI of the token\"}}},\"title\":\"Asset\",\"version\":1},\"userdoc\":{\"events\":{\"TrustedForwarderSet(address,address,address)\":{\"notice\":\"Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\"}},\"kind\":\"user\",\"methods\":{\"burnBatchFrom(address,uint256[],uint256[])\":{\"notice\":\"Burn a batch of tokens from a given account\"},\"burnFrom(address,uint256,uint256)\":{\"notice\":\"Burn a token from a given account\"},\"getAllSplits()\":{\"notice\":\"returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\"},\"getCreatorAddress(uint256)\":{\"notice\":\"Extracts the creator address from a given token id\"},\"getCreatorNonce(uint256)\":{\"notice\":\"Extracts the asset nonce from a given token id\"},\"getOperatorFilterRegistry()\":{\"notice\":\"returns the operator filter registry.\"},\"getRecipients(uint256)\":{\"notice\":\"returns the royalty recipients for each tokenId.\"},\"getRevealNonce(uint256)\":{\"notice\":\"Extracts the abilities and enhancements hash from a given token id\"},\"getRoyaltyManager()\":{\"notice\":\"returns the address of royalty manager.\"},\"getTier(uint256)\":{\"notice\":\"Extracts the tier from a given token id\"},\"getTokenIdByMetadataHash(string)\":{\"notice\":\"returns the tokenId associated with provided metadata hash\"},\"getTokenRoyaltiesSplitter(uint256)\":{\"notice\":\"returns the address of token royalty splitter.\"},\"getTrustedForwarder()\":{\"notice\":\"return the address of the trusted forwarder\"},\"initialize(address,address,string,address,address)\":{\"notice\":\"Initialize the contract\"},\"isBridged(uint256)\":{\"notice\":\"Extracts the bridged flag from a given token id\"},\"isRevealed(uint256)\":{\"notice\":\"Extracts the revealed flag from a given token id\"},\"isTrustedForwarder(address)\":{\"notice\":\"return true if the forwarder is the trusted forwarder\"},\"mint(address,uint256,uint256,string)\":{\"notice\":\"Mint new tokens\"},\"mintBatch(address,uint256[],uint256[],string[])\":{\"notice\":\"Mint new tokens with catalyst tier chosen by the creator\"},\"registerAndSubscribe(address,bool)\":{\"notice\":\"This function is used to register Asset contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.\"},\"royaltyInfo(uint256,uint256)\":{\"notice\":\"EIP 2981 royalty info function to return the royalty receiver and royalty amount\"},\"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\"},\"safeTransferFrom(address,address,uint256,uint256,bytes)\":{\"notice\":\"Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\"},\"setApprovalForAll(address,bool)\":{\"notice\":\"Enable or disable approval for `operator` to manage all of the caller's tokens.\"},\"setBaseURI(string)\":{\"notice\":\"Set a new base URI\"},\"setOperatorRegistry(address)\":{\"notice\":\"sets the operator filter registry address\"},\"setTokenRoyalties(uint256,address,address)\":{\"notice\":\"could be used to deploy splitter and set tokens royalties\"},\"setTokenURI(uint256,string)\":{\"notice\":\"Set a new URI for specific tokenid\"},\"setTrustedForwarder(address)\":{\"notice\":\"Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\"},\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements interface `id`.\"},\"uri(uint256)\":{\"notice\":\"returns full token URI, including baseURI and token metadata URI\"}},\"notice\":\"ERC1155 asset token contractMinting and burning tokens is only allowed through separate authorized contracts\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/asset/contracts/Asset.sol\":\"Asset\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/// @author: manifold.xyz\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\nstruct Recipient {\\n address payable recipient;\\n uint16 bps;\\n}\\n\\ninterface IRoyaltySplitter is IERC165 {\\n /**\\n * @dev Set the splitter recipients. Total bps must total 10000.\\n */\\n function setRecipients(Recipient[] calldata recipients) external;\\n\\n /**\\n * @dev Get the splitter recipients;\\n */\\n function getRecipients() external view returns (Recipient[] memory);\\n}\\n\",\"keccak256\":\"0xc507963f66c4238d25e69d2d05ac5995c549aa89789e89e7a556403221547c6d\",\"license\":\"MIT\"},\"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * EIP-2981\\n */\\ninterface IEIP2981 {\\n /**\\n * bytes4(keccak256(\\\"royaltyInfo(uint256,uint256)\\\")) == 0x2a55205a\\n *\\n * => 0x2a55205a = 0x2a55205a\\n */\\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\\n}\\n\",\"keccak256\":\"0xd5313c1f5939b5a98bc48824082c337a6205d78f6346465fe3c3944de274f6bd\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlUpgradeable.sol\\\";\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\\n function __AccessControl_init() internal onlyInitializing {\\n }\\n\\n function __AccessControl_init_unchained() internal onlyInitializing {\\n }\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n StringsUpgradeable.toHexString(account),\\n \\\" is missing role \\\",\\n StringsUpgradeable.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xfeefb24d068524440e1ba885efdf105d91f83504af3c2d745ffacc4595396831\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControlUpgradeable {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xb8f5302f12138c5561362e88a78d061573e6298b7a1a5afe84a1e2c8d4d5aeaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \\\"./IERC1155Upgradeable.sol\\\";\\nimport \\\"./IERC1155ReceiverUpgradeable.sol\\\";\\nimport \\\"./extensions/IERC1155MetadataURIUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\\n __ERC1155_init_unchained(uri_);\\n }\\n\\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\\n _setURI(uri_);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\\n return\\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\\n bytes4 response\\n ) {\\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[47] private __gap;\\n}\\n\",\"keccak256\":\"0xc3e465e1fdd0e491688ad75ef1b946e1680e7f9f78bf5beeefd6daed8693c856\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\\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\":\"0xffcb29612efb57efc8f0d4897deb5abaeac830022c59a3aa17446d698dbc856b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\\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\",\"keccak256\":\"0xf51f292659a77777c0ed7375a39683d8bee53b86a6e7bd0c76f34ce7aa37a3a8\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1155Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\\n * own tokens and those that they have been approved to use.\\n *\\n * _Available since v3.1._\\n */\\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\\n function __ERC1155Burnable_init() internal onlyInitializing {\\n }\\n\\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\\n }\\n function burn(address account, uint256 id, uint256 value) public virtual {\\n require(\\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\\n \\\"ERC1155: caller is not token owner or approved\\\"\\n );\\n\\n _burn(account, id, value);\\n }\\n\\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\\n require(\\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\\n \\\"ERC1155: caller is not token owner or approved\\\"\\n );\\n\\n _burnBatch(account, ids, values);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x048a492eee88c80ecc0354486e8e0ab99490b44a6fb28833b3cfb45d573f18d7\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1155Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\\n *\\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\\n * clearly identified. Note: While a totalSupply of 1 might mean the\\n * corresponding is an NFT, there is no guarantees that no other token with the\\n * same id are not going to be minted.\\n */\\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\\n function __ERC1155Supply_init() internal onlyInitializing {\\n }\\n\\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\\n }\\n mapping(uint256 => uint256) private _totalSupply;\\n\\n /**\\n * @dev Total amount of tokens in with a given id.\\n */\\n function totalSupply(uint256 id) public view virtual returns (uint256) {\\n return _totalSupply[id];\\n }\\n\\n /**\\n * @dev Indicates whether any token exist with a given id, or not.\\n */\\n function exists(uint256 id) public view virtual returns (bool) {\\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\\n }\\n\\n /**\\n * @dev See {ERC1155-_beforeTokenTransfer}.\\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 override {\\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\\n\\n if (from == address(0)) {\\n for (uint256 i = 0; i < ids.length; ++i) {\\n _totalSupply[ids[i]] += amounts[i];\\n }\\n }\\n\\n if (to == address(0)) {\\n for (uint256 i = 0; i < ids.length; ++i) {\\n uint256 id = ids[i];\\n uint256 amount = amounts[i];\\n uint256 supply = _totalSupply[id];\\n require(supply >= amount, \\\"ERC1155: burn amount exceeds totalSupply\\\");\\n unchecked {\\n _totalSupply[id] = supply - amount;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf7bdbcbb9fcf42997f280db8c02070e9c561406e6971ff680c6c43f92065ac9e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../ERC1155Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev ERC1155 token with storage based token URI management.\\n * Inspired by the ERC721URIStorage extension\\n *\\n * _Available since v4.6._\\n */\\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\\n function __ERC1155URIStorage_init() internal onlyInitializing {\\n __ERC1155URIStorage_init_unchained();\\n }\\n\\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\\n _baseURI = \\\"\\\";\\n }\\n using StringsUpgradeable for uint256;\\n\\n // Optional base URI\\n string private _baseURI;\\n\\n // Optional mapping for token URIs\\n mapping(uint256 => string) private _tokenURIs;\\n\\n /**\\n * @dev See {IERC1155MetadataURI-uri}.\\n *\\n * This implementation returns the concatenation of the `_baseURI`\\n * and the token-specific uri if the latter is set\\n *\\n * This enables the following behaviors:\\n *\\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\\n * is empty per default);\\n *\\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\\n * which in most cases will contain `ERC1155._uri`;\\n *\\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\\n * uri value set, then the result is empty.\\n */\\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\\n string memory tokenURI = _tokenURIs[tokenId];\\n\\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\\n }\\n\\n /**\\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\\n */\\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\\n _tokenURIs[tokenId] = tokenURI;\\n emit URI(uri(tokenId), tokenId);\\n }\\n\\n /**\\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\\n */\\n function _setBaseURI(string memory baseURI) internal virtual {\\n _baseURI = baseURI;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[48] private __gap;\\n}\\n\",\"keccak256\":\"0x9a1218747a17239e2fcab2efc14099379387f114c7ad22c69a23b7d67ec0eaa2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \\\"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\\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\",\"keccak256\":\"0xa350df12a8c10e821af05e0863f44e8317a0efa44df27bfd5dc1d63fdfa3c448\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\\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\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\\\";\\nimport \\\"./math/SignedMathUpgradeable.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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\":\"0xb96dc79b65b7c37937919dcdb356a969ce0aa2e8338322bf4dc027a3c9c9a7eb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\\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\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\\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\":\"0x2bc0007987c229ae7624eb29be6a9b84f6a6a5872f76248b15208b131ea41c4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\\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\":\"0x88f6b7bba3ee33eeb741f9a0f5bc98b6e6e352d0fe4905377bb328590f84095a\",\"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\"},\"@sandbox-smart-contracts/asset/contracts/Asset.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {\\n AccessControlUpgradeable,\\n ContextUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\\\";\\nimport {\\n ERC1155BurnableUpgradeable,\\n ERC1155Upgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\\\";\\nimport {\\n ERC1155SupplyUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\\\";\\nimport {\\n ERC1155URIStorageUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\\\";\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {\\n ERC2771HandlerUpgradeable\\n} from \\\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\\\";\\nimport {\\n MultiRoyaltyDistributor\\n} from \\\"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\\\";\\nimport {\\n OperatorFiltererUpgradeable,\\n IOperatorFilterRegistry\\n} from \\\"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\\\";\\nimport {TokenIdUtils} from \\\"./libraries/TokenIdUtils.sol\\\";\\nimport {IAsset} from \\\"./interfaces/IAsset.sol\\\";\\nimport {ITokenUtils, IRoyaltyUGC} from \\\"./interfaces/ITokenUtils.sol\\\";\\n\\n/// @title Asset\\n/// @author The Sandbox\\n/// @notice ERC1155 asset token contract\\n/// @notice Minting and burning tokens is only allowed through separate authorized contracts\\n/// @dev This contract is final and should not be inherited\\ncontract Asset is\\n IAsset,\\n Initializable,\\n ERC2771HandlerUpgradeable,\\n ERC1155BurnableUpgradeable,\\n AccessControlUpgradeable,\\n ERC1155SupplyUpgradeable,\\n ERC1155URIStorageUpgradeable,\\n OperatorFiltererUpgradeable,\\n MultiRoyaltyDistributor,\\n ITokenUtils\\n{\\n using TokenIdUtils for uint256;\\n\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER_ROLE\\\");\\n bytes32 public constant BURNER_ROLE = keccak256(\\\"BURNER_ROLE\\\");\\n bytes32 public constant MODERATOR_ROLE = keccak256(\\\"MODERATOR_ROLE\\\");\\n\\n // mapping of ipfs metadata token hash to token id\\n mapping(string => uint256) public hashUsed;\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @notice Initialize the contract\\n /// @param forwarder The address of the trusted forwarder\\n /// @param assetAdmin The address of the asset admin\\n /// @param baseUri The base URI for the token metadata\\n /// @param commonSubscription The address of the operator filter subscription\\n /// @param _manager The address of the royalty manager\\n function initialize(\\n address forwarder,\\n address assetAdmin,\\n string memory baseUri,\\n address commonSubscription,\\n address _manager\\n ) external initializer {\\n _setBaseURI(baseUri);\\n __AccessControl_init();\\n __ERC1155Supply_init();\\n __ERC2771Handler_init(forwarder);\\n __ERC1155Burnable_init();\\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\\n __OperatorFilterer_init(commonSubscription, true);\\n __MultiRoyaltyDistributor_init(_manager);\\n }\\n\\n /// @notice Mint new tokens\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param id The id of the token to mint\\n /// @param amount The amount of the token to mint\\n /// @param metadataHash The metadata hash of the token to mint\\n function mint(\\n address to,\\n uint256 id,\\n uint256 amount,\\n string memory metadataHash\\n ) external onlyRole(MINTER_ROLE) {\\n _setMetadataHash(id, metadataHash);\\n _mint(to, id, amount, \\\"\\\");\\n address creator = id.getCreatorAddress();\\n _setTokenRoyalties(id, payable(creator), creator);\\n }\\n\\n /// @notice Mint new tokens with catalyst tier chosen by the creator\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param ids The ids of the tokens to mint\\n /// @param amounts The amounts of the tokens to mint\\n /// @param metadataHashes The metadata hashes of the tokens to mint\\n function mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n string[] memory metadataHashes\\n ) external onlyRole(MINTER_ROLE) {\\n require(ids.length == metadataHashes.length, \\\"Asset: 1-Array mismatch\\\");\\n require(ids.length == amounts.length, \\\"Asset: 2-Array mismatch\\\");\\n for (uint256 i = 0; i < ids.length; i++) {\\n _setMetadataHash(ids[i], metadataHashes[i]);\\n }\\n _mintBatch(to, ids, amounts, \\\"\\\");\\n for (uint256 i; i < ids.length; i++) {\\n address creator = ids[i].getCreatorAddress();\\n _setTokenRoyalties(ids[i], payable(creator), creator);\\n }\\n }\\n\\n /// @notice Burn a token from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @param account The account to burn tokens from\\n /// @param id The token id to burn\\n /// @param amount The amount of tokens to burn\\n function burnFrom(\\n address account,\\n uint256 id,\\n uint256 amount\\n ) external onlyRole(BURNER_ROLE) {\\n _burn(account, id, amount);\\n }\\n\\n /// @notice Burn a batch of tokens from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @dev The length of the ids and amounts arrays must be the same\\n /// @param account The account to burn tokens from\\n /// @param ids An array of token ids to burn\\n /// @param amounts An array of amounts of tokens to burn\\n function burnBatchFrom(\\n address account,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external onlyRole(BURNER_ROLE) {\\n _burnBatch(account, ids, amounts);\\n }\\n\\n /// @notice Set a new URI for specific tokenid\\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\\n /// @param tokenId The token id to set URI for\\n /// @param metadata The new URI for asset's metadata\\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\\n _setURI(tokenId, metadata);\\n }\\n\\n /// @notice Set a new base URI\\n /// @param baseURI The new base URI\\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n _setBaseURI(baseURI);\\n }\\n\\n /// @notice returns full token URI, including baseURI and token metadata URI\\n /// @param tokenId The token id to get URI for\\n /// @return tokenURI the URI of the token\\n function uri(uint256 tokenId)\\n public\\n view\\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\\n returns (string memory tokenURI)\\n {\\n return ERC1155URIStorageUpgradeable.uri(tokenId);\\n }\\n\\n /// @notice returns the tokenId associated with provided metadata hash\\n /// @param metadataHash The metadata hash to get tokenId for\\n /// @return tokenId the tokenId associated with the metadata hash\\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256 tokenId) {\\n return hashUsed[metadataHash];\\n }\\n\\n /// @notice sets the metadata hash for a given tokenId\\n /// @param tokenId The tokenId to set metadata hash for\\n /// @param metadataHash The metadata hash to set\\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\\n if (hashUsed[metadataHash] != 0) {\\n require(hashUsed[metadataHash] == tokenId, \\\"Asset: Hash already used\\\");\\n } else {\\n hashUsed[metadataHash] = tokenId;\\n _setURI(tokenId, metadataHash);\\n }\\n }\\n\\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\\n /// @dev Change the address of the trusted forwarder for meta-TX\\n /// @param trustedForwarder The new trustedForwarder\\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(trustedForwarder != address(0), \\\"Asset: Zero address\\\");\\n _setTrustedForwarder(trustedForwarder);\\n }\\n\\n /// @notice Query if a contract implements interface `id`.\\n /// @param id the interface identifier, as specified in ERC-165.\\n /// @return supported `true` if the contract implements `id`.\\n function supportsInterface(bytes4 id)\\n public\\n view\\n virtual\\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\\n returns (bool supported)\\n {\\n return id == type(IRoyaltyUGC).interfaceId || super.supportsInterface(id);\\n }\\n\\n function _msgSender()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (address sender)\\n {\\n return ERC2771HandlerUpgradeable._msgSender();\\n }\\n\\n function _msgData()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (bytes calldata msgData)\\n {\\n return ERC2771HandlerUpgradeable._msgData();\\n }\\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\\n }\\n\\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\\n /// @param from address from which tokens are transfered.\\n /// @param to address to which the token will be transfered.\\n /// @param ids ids of each token type transfered.\\n /// @param amounts amount of each token type transfered.\\n /// @param data additional data accompanying the transfer.\\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 onlyAllowedOperator(from) {\\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\\n }\\n\\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\\n /// @param approved whether to approve or revoke\\n function setApprovalForAll(address operator, bool approved)\\n public\\n virtual\\n override\\n onlyAllowedOperatorApproval(operator)\\n {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\\n /// @param from address from which tokens are transfered.\\n /// @param to address to which the token will be transfered.\\n /// @param id the token type transfered.\\n /// @param amount amount of token transfered.\\n /// @param data additional data accompanying the transfer.\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 amount,\\n bytes memory data\\n ) public virtual override onlyAllowedOperator(from) {\\n require(from == _msgSender() || isApprovedForAll(from, _msgSender()), \\\"Asset: Transfer error\\\");\\n _safeTransferFrom(from, to, id, amount, data);\\n }\\n\\n /// @notice could be used to deploy splitter and set tokens royalties\\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\\n /// @param recipient the royalty recipient for the splitter of the creator.\\n /// @param creator the creator of the tokens.\\n function setTokenRoyalties(\\n uint256 tokenId,\\n address payable recipient,\\n address creator\\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\\n _setTokenRoyalties(tokenId, recipient, creator);\\n }\\n\\n /// @notice Extracts the creator address from a given token id\\n /// @param tokenId The token id to extract the creator address from\\n /// @return creator The asset creator address\\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\\n return TokenIdUtils.getCreatorAddress(tokenId);\\n }\\n\\n /// @notice Extracts the tier from a given token id\\n /// @param tokenId The token id to extract the tier from\\n /// @return tier The asset tier, determined by the catalyst used to create it\\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\\n return TokenIdUtils.getTier(tokenId);\\n }\\n\\n /// @notice Extracts the revealed flag from a given token id\\n /// @param tokenId The token id to extract the revealed flag from\\n /// @return revealed Whether the asset is revealed or not\\n function isRevealed(uint256 tokenId) external pure returns (bool revealed) {\\n return TokenIdUtils.isRevealed(tokenId);\\n }\\n\\n /// @notice Extracts the asset nonce from a given token id\\n /// @param tokenId The token id to extract the asset nonce from\\n /// @return creatorNonce The asset creator nonce\\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16 creatorNonce) {\\n return TokenIdUtils.getCreatorNonce(tokenId);\\n }\\n\\n /// @notice Extracts the abilities and enhancements hash from a given token id\\n /// @param tokenId The token id to extract reveal nonce from\\n /// @return revealNonce The reveal nonce of the asset\\n function getRevealNonce(uint256 tokenId) external pure returns (uint16 revealNonce) {\\n return TokenIdUtils.getRevealNonce(tokenId);\\n }\\n\\n /// @notice Extracts the bridged flag from a given token id\\n /// @param tokenId The token id to extract the bridged flag from\\n /// @return bridged Whether the asset is bridged or not\\n function isBridged(uint256 tokenId) external pure returns (bool bridged) {\\n return TokenIdUtils.isBridged(tokenId);\\n }\\n\\n /// @notice This function is used to register Asset contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.\\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\\n /// @param subscribe bool to signify subscription \\\"true\\\"\\\" or to copy the list \\\"false\\\".\\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\\n external\\n onlyRole(DEFAULT_ADMIN_ROLE)\\n {\\n require(subscriptionOrRegistrantToCopy != address(0), \\\"Asset: Zero address\\\");\\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\\n }\\n\\n /// @notice sets the operator filter registry address\\n /// @param registry the address of the registry\\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(registry != address(0), \\\"Asset: Zero address\\\");\\n OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xec424d1b47729418c857874d59c86ff15f15134d83d4f4be8e43badc0c244d3d\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\n/// @title Asset interface\\n/// @author The Sandbox\\ninterface IAsset {\\n // AssetData reflects the asset tokenId structure\\n // Refer to TokenIdUtils.sol\\n struct AssetData {\\n uint256 tokenId;\\n address creator;\\n uint256 amount;\\n uint8 tier;\\n uint16 creatorNonce;\\n bool revealed;\\n string metadataHash;\\n bool bridged;\\n }\\n\\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\\n\\n /// @notice Mint new tokens\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param id The id of the token to mint\\n /// @param amount The amount of the token to mint\\n /// @param metadataHash The metadata hash of the token to mint\\n function mint(\\n address to,\\n uint256 id,\\n uint256 amount,\\n string memory metadataHash\\n ) external;\\n\\n /// @notice Mint new tokens with catalyst tier chosen by the creator\\n /// @dev Only callable by the minter role\\n /// @param to The address of the recipient\\n /// @param ids The ids of the tokens to mint\\n /// @param amounts The amounts of the tokens to mint\\n /// @param metadataHashes The metadata hashes of the tokens to mint\\n function mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts,\\n string[] memory metadataHashes\\n ) external;\\n\\n /// @notice Burn a token from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @param account The account to burn tokens from\\n /// @param id The token id to burn\\n /// @param amount The amount of tokens to burn\\n function burnFrom(\\n address account,\\n uint256 id,\\n uint256 amount\\n ) external;\\n\\n /// @notice Burn a batch of tokens from a given account\\n /// @dev Only the minter role can burn tokens\\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\\n /// @dev The length of the ids and amounts arrays must be the same\\n /// @param account The account to burn tokens from\\n /// @param ids An array of token ids to burn\\n /// @param amounts An array of amounts of tokens to burn\\n function burnBatchFrom(\\n address account,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external;\\n\\n /// @notice returns the tokenId associated with provided metadata hash\\n /// @param metadataHash The metadata hash to get tokenId for\\n /// @return tokenId the tokenId associated with the metadata hash\\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256 tokenId);\\n}\\n\",\"keccak256\":\"0xbc79058becff31b0b7f465d92a89aad25f561dbdb5a2cd068d51c7ef93b4fbfe\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {IRoyaltyUGC} from \\\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\\\";\\n\\n/// @title TokenUtils interface\\n/// @author The Sandbox\\ninterface ITokenUtils is IRoyaltyUGC {\\n /// @notice Extracts the tier from a given token id\\n /// @param tokenId The token id to extract the tier from\\n /// @return tier The asset tier, determined by the catalyst used to create it\\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\\n\\n /// @notice Extracts the revealed flag from a given token id\\n /// @param tokenId The token id to extract the revealed flag from\\n /// @return revealed Whether the asset is revealed or not\\n function isRevealed(uint256 tokenId) external pure returns (bool revealed);\\n\\n /// @notice Extracts the asset nonce from a given token id\\n /// @param tokenId The token id to extract the asset nonce from\\n /// @return creatorNonce The asset creator nonce\\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16 creatorNonce);\\n\\n /// @notice Extracts the abilities and enhancements hash from a given token id\\n /// @param tokenId The token id to extract reveal nonce from\\n /// @return revealNonce The reveal nonce of the asset\\n function getRevealNonce(uint256 tokenId) external pure returns (uint16 revealNonce);\\n\\n /// @notice Extracts the bridged flag from a given token id\\n /// @param tokenId The token id to extract the bridged flag from\\n /// @return bridged Whether the asset is bridged or not\\n function isBridged(uint256 tokenId) external pure returns (bool bridged);\\n\\n /// @notice Extracts the creator address from a given token id\\n /// @param tokenId The token id to extract the creator address from\\n /// @return creator The asset creator address\\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\\n}\\n\",\"keccak256\":\"0x3279c929c7193756da5147e980b053d68a2ee524514bbed78d28b8909f694357\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IAsset} from \\\"../interfaces/IAsset.sol\\\";\\n\\n/// @title TokenIdUtils library\\n/// @author The Sandbox\\n/// @notice Contains utility functions for token ids\\nlibrary TokenIdUtils {\\n // Layer masks\\n uint256 public constant TIER_MASK = 0xFF;\\n uint256 public constant NONCE_MASK = 0xFFFF;\\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\\n uint256 public constant BRIDGED_MASK = 0x1;\\n\\n // Bit shifts\\n uint256 public constant CREATOR_SHIFT = 0;\\n uint256 public constant TIER_SHIFT = 160;\\n uint256 public constant NONCE_SHIFT = 168;\\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\\n uint256 public constant BRIDGED_SHIFT = 200;\\n\\n /// @notice Generates a token id for a given asset\\n /// @dev The token id is generated by concatenating the following fields:\\n /// @dev creator address, tier, creator nonce, reveal nonce and bridged boolean\\n /// @dev The first 160 bits are the creator address\\n /// @dev The next 8 bits are the tier\\n /// @dev The next 16 bits are the creator nonce\\n /// @dev The next 16 bits are for reveal nonce.\\n /// @dev The last bit is for bridged boolean\\n /// @param creator The address of the creator of the asset\\n /// @param tier The tier of the asset determined by the catalyst used to create it\\n /// @param creatorNonce The nonce of the asset creator\\n /// @param revealNonce The reveal nonce of the asset\\n /// @param bridged Whether the asset is bridged or not\\n /// @return tokenId The generated token id\\n function generateTokenId(\\n address creator,\\n uint8 tier,\\n uint16 creatorNonce,\\n uint16 revealNonce,\\n bool bridged\\n ) internal pure returns (uint256 tokenId) {\\n uint160 creatorAddress = uint160(creator);\\n\\n tokenId = tokenId =\\n uint256(creatorAddress) |\\n (uint256(tier) << TIER_SHIFT) |\\n (uint256(creatorNonce) << NONCE_SHIFT) |\\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\\n\\n return tokenId;\\n }\\n\\n /// @notice Extracts the creator address from a given token id\\n /// @param tokenId The token id to extract the creator address from\\n /// @return creator The asset creator address\\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\\n creator = address(uint160(tokenId));\\n return creator;\\n }\\n\\n /// @notice Extracts the tier from a given token id\\n /// @param tokenId The token id to extract the tier from\\n /// @return tier The asset tier, determined by the catalyst used to create it\\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\\n return tier;\\n }\\n\\n /// @notice Extracts the revealed flag from a given token id\\n /// @param tokenId The token id to extract the revealed flag from\\n /// @return isRevealed Whether the asset is revealed or not\\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\\n uint16 revealNonce = getRevealNonce(tokenId);\\n return revealNonce != 0;\\n }\\n\\n /// @notice Extracts the asset nonce from a given token id\\n /// @param tokenId The token id to extract the asset nonce from\\n /// @return creatorNonce The asset creator nonce\\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\\n return creatorNonce;\\n }\\n\\n /// @notice Extracts the abilities and enhancements hash from a given token id\\n /// @param tokenId The token id to extract reveal nonce from\\n /// @return revealNonce The reveal nonce of the asset\\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\\n return revealNonce;\\n }\\n\\n /// @notice Extracts the bridged flag from a given token id\\n /// @param tokenId The token id to extract the bridged flag from\\n /// @return bridged Whether the asset is bridged or not\\n function isBridged(uint256 tokenId) internal pure returns (bool) {\\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\\n return bridged;\\n }\\n\\n /// @notice Extracts the asset data from a given token id\\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\\n /// @param tokenId The token id to extract the asset data from\\n /// @return data The asset data struct\\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\\n data.creator = getCreatorAddress(tokenId);\\n data.tier = getTier(tokenId);\\n data.revealed = isRevealed(tokenId);\\n data.creatorNonce = getCreatorNonce(tokenId);\\n data.bridged = isBridged(tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x68a7d6f1ff700f2c1cc9b20e89ccd9aa7fced45a54cc1e3c361136c57d0e4511\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\nabstract contract ERC2771HandlerAbstract {\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function isTrustedForwarder(address forwarder) external view returns (bool) {\\n return _isTrustedForwarder(forwarder);\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual returns (address sender) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n // The assembly code is more direct than the Solidity version using `abi.decode`.\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\\n }\\n } else {\\n sender = msg.sender;\\n }\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual returns (bytes calldata) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n return msg.data[:msg.data.length - 20];\\n } else {\\n return msg.data;\\n }\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n /// @dev this function must be IMPLEMENTED\\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xc4f349865ea7146f51b69f1edacdef60e0a2a7cf4dab538a5ae53ee9a0036231\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {ERC2771HandlerAbstract} from \\\"./ERC2771HandlerAbstract.sol\\\";\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\\n address private _trustedForwarder;\\n\\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\\n /// @param oldTrustedForwarder old trusted forwarder\\n /// @param newTrustedForwarder new trusted forwarder\\n /// @param operator the sender of the transaction\\n event TrustedForwarderSet(\\n address indexed oldTrustedForwarder,\\n address indexed newTrustedForwarder,\\n address indexed operator\\n );\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\\n __ERC2771Handler_init_unchained(forwarder);\\n }\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\\n _setTrustedForwarder(forwarder);\\n }\\n\\n /// @notice return the address of the trusted forwarder\\n /// @return return the address of the trusted forwarder\\n function getTrustedForwarder() external view returns (address) {\\n return _trustedForwarder;\\n }\\n\\n /// @notice set the address of the trusted forwarder\\n /// @param newForwarder the address of the new forwarder.\\n function _setTrustedForwarder(address newForwarder) internal virtual {\\n require(newForwarder != _trustedForwarder, \\\"ERC2771HandlerUpgradeable: forwarder already set\\\");\\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\\n _trustedForwarder = newForwarder;\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\\n return forwarder == _trustedForwarder;\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual override returns (address sender) {\\n return super._msgSender();\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual override returns (bytes calldata) {\\n return super._msgData();\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf9767f843906800128ee86bd89bc2088e8f1b633ed4c800f477beb4e604f81de\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {IOperatorFilterRegistry} from \\\"./interfaces/IOperatorFilterRegistry.sol\\\";\\nimport {ContextUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\\\";\\n\\n///@title OperatorFiltererUpgradeable\\n///@author The Sandbox\\n///@notice This contract would subscribe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's address could be set using a setter which could be implemented in inheriting contract\\nabstract contract OperatorFiltererUpgradeable is Initializable, ContextUpgradeable {\\n event OperatorFilterRegistrySet(address indexed registry);\\n\\n IOperatorFilterRegistry private operatorFilterRegistry;\\n\\n // solhint-disable-next-line func-name-mixedcase\\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\\n // order for the modifier to filter addresses.\\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\\n }\\n\\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\\n if (address(operatorFilterRegistry).code.length > 0) {\\n if (!operatorFilterRegistry.isRegistered(address(this))) {\\n if (subscribe) {\\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\\n } else {\\n if (subscriptionOrRegistrantToCopy != address(0)) {\\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\\n } else {\\n operatorFilterRegistry.register(address(this));\\n }\\n }\\n }\\n }\\n }\\n\\n modifier onlyAllowedOperator(address from) virtual {\\n // Check registry code length to facilitate testing in environments without a deployed registry.\\n if (address(operatorFilterRegistry).code.length > 0) {\\n // Allow spending tokens from addresses with balance\\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\\n // from an EOA.\\n if (from == _msgSender()) {\\n _;\\n return;\\n }\\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), _msgSender())) {\\n revert(\\\"Operator Not Allowed\\\");\\n }\\n }\\n _;\\n }\\n\\n modifier onlyAllowedOperatorApproval(address operator) virtual {\\n // Check registry code length to facilitate testing in environments without a deployed registry.\\n if (address(operatorFilterRegistry).code.length > 0) {\\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\\n revert(\\\"Operator Not Allowed\\\");\\n }\\n }\\n _;\\n }\\n\\n /// @notice returns the operator filter registry.\\n /// @return operatorFilterRegistryAddress address of operator filter registry contract.\\n function getOperatorFilterRegistry() external view returns (IOperatorFilterRegistry operatorFilterRegistryAddress) {\\n return _getOperatorFilterRegistry();\\n }\\n\\n /// @notice internal method to set the operator filter registry\\n /// @param registry address the registry.\\n function _setOperatorFilterRegistry(address registry) internal {\\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\\n emit OperatorFilterRegistrySet(registry);\\n }\\n\\n /// @notice internal method to get the operator filter registry.\\n function _getOperatorFilterRegistry()\\n internal\\n view\\n returns (IOperatorFilterRegistry operatorFilterRegistryAddress)\\n {\\n return operatorFilterRegistry;\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xbd7e2d8ee93a31af7057933a0ea415f7c1ab90dbfbb8e41085ef23ed98ead3af\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title IOperatorFilterRegistry\\n/// @notice Interface for managing operators and filtering.\\ninterface IOperatorFilterRegistry {\\n ///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\\n /// true if supplied registrant address is not registered.\\n function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed);\\n\\n ///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\\n function register(address registrant) external;\\n\\n ///@notice Registers an address with the registry and \\\"subscribes\\\" to another address's filtered operators and codeHashes.\\n function registerAndSubscribe(address registrant, address subscription) external;\\n\\n ///@notice Registers an address with the registry and copies the filtered operators and codeHashes from another\\n /// address without subscribing.\\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\\n\\n ///@notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\\n /// Note that this does not remove any filtered addresses or codeHashes.\\n /// Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\\n function unregister(address addr) external;\\n\\n ///@notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\\n function updateOperator(\\n address registrant,\\n address operator,\\n bool filtered\\n ) external;\\n\\n ///@notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\\n function updateOperators(\\n address registrant,\\n address[] calldata operators,\\n bool filtered\\n ) external;\\n\\n ///@notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\\n function updateCodeHash(\\n address registrant,\\n bytes32 codehash,\\n bool filtered\\n ) external;\\n\\n ///@notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\\n function updateCodeHashes(\\n address registrant,\\n bytes32[] calldata codeHashes,\\n bool filtered\\n ) external;\\n\\n ///@notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\\n /// subscription if present.\\n /// Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\\n /// subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\\n /// used.\\n function subscribe(address registrant, address registrantToSubscribe) external;\\n\\n ///@notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\\n function unsubscribe(address registrant, bool copyExistingEntries) external;\\n\\n ///@notice Get the subscription address of a given registrant, if any.\\n function subscriptionOf(address addr) external returns (address registrant);\\n\\n ///@notice Get the set of addresses subscribed to a given registrant.\\n /// Note that order is not guaranteed as updates are made.\\n function subscribers(address registrant) external returns (address[] memory subscribersList);\\n\\n ///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\\n /// Note that order is not guaranteed as updates are made.\\n function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress);\\n\\n ///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\\n function copyEntriesOf(address registrant, address registrantToCopy) external;\\n\\n ///@notice Returns true if operator is filtered by a given address or its subscription.\\n function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered);\\n\\n ///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered);\\n\\n ///@notice Returns true if a codeHash is filtered by a given address or its subscription.\\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered);\\n\\n ///@notice Returns a list of filtered operators for a given address or its subscription.\\n function filteredOperators(address addr) external returns (address[] memory operatorList);\\n\\n ///@notice Returns the set of filtered codeHashes for a given address or its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList);\\n\\n ///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\\n /// its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredOperatorAt(address registrant, uint256 index) external returns (address operator);\\n\\n ///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\\n /// its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash);\\n\\n ///@notice Returns true if an address has registered\\n function isRegistered(address addr) external returns (bool registered);\\n\\n ///@dev Convenience method to compute the code hash of an arbitrary contract\\n function codeHashOf(address addr) external returns (bytes32 codeHash);\\n}\\n\",\"keccak256\":\"0x3954f1465330c8645891a1d566723f9804515632be2025edd02b00a0e53d2f30\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {ERC165Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\\\";\\nimport {IMultiRoyaltyDistributor, IMultiRoyaltyRecipients} from \\\"./interfaces/IMultiRoyaltyDistributor.sol\\\";\\nimport {\\n IRoyaltySplitter,\\n IERC165\\n} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\nimport {IEIP2981} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\\\";\\nimport {IRoyaltyManager, Recipient} from \\\"./interfaces/IRoyaltyManager.sol\\\";\\n\\n/// @title MultiRoyaltyDistributor\\n/// @author The Sandbox\\n/// @dev The MultiRoyaltyDistributor contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to split its royalty between the creator and Sandbox and use it for every token minted by that creator.\\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\\n address private royaltyManager;\\n\\n mapping(uint256 => address payable) private _tokenRoyaltiesSplitter;\\n uint256[] private _tokensWithRoyalties;\\n\\n // solhint-disable-next-line func-name-mixedcase\\n function __MultiRoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing {\\n _setRoyaltyManager(_royaltyManager);\\n __ERC165_init_unchained();\\n }\\n\\n /// @notice Query if a contract implements interface `id`.\\n /// @param interfaceId the interface identifier, as specified in ERC-165.\\n /// @return isSupported `true` if the contract implements `id`.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC165Upgradeable, IERC165)\\n returns (bool isSupported)\\n {\\n return\\n interfaceId == type(IEIP2981).interfaceId ||\\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\\n interfaceId == type(IMultiRoyaltyRecipients).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /// @notice sets token royalty\\n /// @dev deploys a splitter if a creator doesn't have one\\n /// @param tokenId id of token\\n /// @param recipient royalty recipient\\n /// @param creator of the token\\n function _setTokenRoyalties(\\n uint256 tokenId,\\n address payable recipient,\\n address creator\\n ) internal {\\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\\n\\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\\n if (_tokenRoyaltiesSplitter[tokenId] != creatorSplitterAddress) {\\n _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress);\\n }\\n } else {\\n _tokensWithRoyalties.push(tokenId);\\n _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress);\\n }\\n }\\n\\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\\n /// @param tokenId of the token for which the royalty is needed to be distributed\\n /// @param value the amount on which the royalty is calculated\\n /// @return receiver address the royalty receiver\\n /// @return royaltyAmount value the EIP2981 royalty\\n function royaltyInfo(uint256 tokenId, uint256 value)\\n public\\n view\\n override\\n returns (address receiver, uint256 royaltyAmount)\\n {\\n (address payable _defaultRoyaltyReceiver, uint16 _defaultRoyaltyBPS) =\\n IRoyaltyManager(royaltyManager).getRoyaltyInfo();\\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\\n }\\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\\n }\\n return (address(0), 0);\\n }\\n\\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\\n /// @return splits the royalty receiver's array\\n function getAllSplits() external view override returns (address payable[] memory splits) {\\n uint256 startingIndex;\\n uint256 endingIndex = _tokensWithRoyalties.length;\\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\\n if (_defaultRoyaltyReceiver != address(0)) {\\n splits = new address payable[](1 + _tokensWithRoyalties.length);\\n splits[0] = _defaultRoyaltyReceiver;\\n startingIndex = 1;\\n ++endingIndex;\\n } else {\\n // unreachable in practice\\n splits = new address payable[](_tokensWithRoyalties.length);\\n }\\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\\n }\\n }\\n\\n /// @notice returns the royalty recipients for each tokenId.\\n /// @dev returns the default address for tokens with no recipients.\\n /// @param tokenId is the token id for which the recipient should be returned.\\n /// @return recipients array of royalty recipients for the token\\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory recipients) {\\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\\n if (splitterAddress != address(0)) {\\n return IRoyaltySplitter(splitterAddress).getRecipients();\\n }\\n recipients = new Recipient[](1);\\n recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\\n return recipients;\\n }\\n\\n /// @notice internal function to set the token royalty splitter\\n /// @param tokenId id of token\\n /// @param splitterAddress address of the splitter contract\\n function _setTokenRoyaltiesSplitter(uint256 tokenId, address payable splitterAddress) internal {\\n _tokenRoyaltiesSplitter[tokenId] = splitterAddress;\\n emit TokenRoyaltySplitterSet(tokenId, splitterAddress);\\n }\\n\\n /// @notice returns the address of token royalty splitter.\\n /// @param tokenId is the token id for which royalty splitter should be returned.\\n /// @return splitterAddress address of royalty splitter for the token\\n function getTokenRoyaltiesSplitter(uint256 tokenId) external view returns (address payable splitterAddress) {\\n return _tokenRoyaltiesSplitter[tokenId];\\n }\\n\\n /// @notice returns the address of royalty manager.\\n /// @return managerAddress address of royalty manager.\\n function getRoyaltyManager() external view returns (address managerAddress) {\\n return royaltyManager;\\n }\\n\\n /// @notice set royalty manager address\\n /// @param _royaltyManager address of royalty manager to set\\n function _setRoyaltyManager(address _royaltyManager) internal {\\n royaltyManager = _royaltyManager;\\n emit RoyaltyManagerSet(_royaltyManager);\\n }\\n\\n uint256[47] private __gap;\\n}\\n\",\"keccak256\":\"0x83df434fc679c5cb006ecadc3d8dcd8d533ce74b09cb85da0f4bb1906303fccf\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {IMultiRoyaltyRecipients} from \\\"./IMultiRoyaltyRecipients.sol\\\";\\nimport {Recipient} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\n\\n///Multi-receiver EIP2981 reference override implementation\\ninterface IMultiRoyaltyDistributor is IERC165, IMultiRoyaltyRecipients {\\n event TokenRoyaltyRemoved(uint256 tokenId);\\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\\n\\n event DefaultRoyaltyReceiverSet(address indexed recipient);\\n\\n event RoyaltyRecipientSet(address indexed splitter, address indexed recipient);\\n\\n event TokenRoyaltySplitterSet(uint256 tokenId, address splitterAddress);\\n\\n event RoyaltyManagerSet(address indexed _royaltyManager);\\n\\n struct TokenRoyaltyConfig {\\n uint256 tokenId;\\n uint16 royaltyBPS;\\n Recipient[] recipients;\\n }\\n\\n ///@notice Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\\n ///@param tokenId The ID of the token for which to set the royalties.\\n ///@param recipient The address that will receive the royalties.\\n ///@param creator The creator's address for the token.\\n function setTokenRoyalties(\\n uint256 tokenId,\\n address payable recipient,\\n address creator\\n ) external;\\n\\n ///@notice Helper function to get all splits contracts\\n ///@return an array of royalty receiver\\n function getAllSplits() external view returns (address payable[] memory);\\n}\\n\",\"keccak256\":\"0xf92f070d05d616d07b95c97417e007a0082c88ac92a3d20c8b0bfce2e7aef41f\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Recipient} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\n\\n/// Multi-receiver EIP2981 implementation\\ninterface IMultiRoyaltyRecipients is IERC165 {\\n /// @dev Helper function to get all recipients\\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\\n}\\n\",\"keccak256\":\"0x2c6e5455253182472f0c7ef21c46279581e281d542b511b96cb693baa0863f33\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Recipient} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\n\\n/// @title IRoyaltyManager\\n/// @notice interface for RoyaltyManager Contract\\ninterface IRoyaltyManager {\\n event RecipientSet(address indexed commonRecipient);\\n\\n event SplitSet(uint16 commonSplit);\\n\\n event RoyaltySet(uint16 royaltyBps, address indexed contractAddress);\\n\\n event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder);\\n\\n event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress);\\n\\n ///@notice sets the common recipient\\n ///@param _commonRecipient is the common recipient for all the splitters\\n function setRecipient(address payable _commonRecipient) external;\\n\\n ///@notice sets the common split\\n ///@param commonSplit split for the common recipient\\n function setSplit(uint16 commonSplit) external;\\n\\n ///@notice to be called by the splitters to get the common recipient and split\\n ///@return recipient which has the common recipient and split\\n function getCommonRecipient() external view returns (Recipient memory recipient);\\n\\n ///@notice returns the amount of basis points allocated to the creator\\n ///@return creatorSplit the share of creator in bps\\n function getCreatorSplit() external view returns (uint16 creatorSplit);\\n\\n ///@notice returns the commonRecipient and EIP2981 royalty split\\n ///@return recipient address of common royalty recipient\\n ///@return royaltySplit contract EIP2981 royalty bps\\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit);\\n\\n ///@notice deploys splitter for creator\\n ///@param creator the address of the creator\\n ///@param recipient the wallet of the recipient where they would receive their royalty\\n ///@return creatorSplitterAddress splitter's address deployed for creator\\n function deploySplitter(address creator, address payable recipient)\\n external\\n returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the address of splitter of a creator.\\n ///@param creator the address of the creator\\n ///@return creatorSplitterAddress splitter's address deployed for a creator\\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the EIP2981 royalty split\\n ///@param _contractAddress the address of the contract for which the royalty is required\\n ///@return royaltyBps royalty bps of the contract\\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\\n\\n ///@notice sets the trustedForwarder address to be used by the splitters\\n ///@param _newForwarder is the new trusted forwarder address\\n function setTrustedForwarder(address _newForwarder) external;\\n\\n ///@notice get the current trustedForwarder address\\n ///@return trustedForwarder address of current trusted Forwarder\\n function getTrustedForwarder() external view returns (address trustedForwarder);\\n}\\n\",\"keccak256\":\"0x5e8e149845df288a5d0ddfa00407ebda15d024e8caf1057822670a5232fee93f\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title IRoyaltyUGC\\n/// @notice interface define function for managing creator of UGC (User-Generated Content)\\ninterface IRoyaltyUGC {\\n ///@notice Gets the address of the creator associated with a specific token.\\n ///@param tokenId the Id of token to retrieve the creator address for\\n ///@return creator the address of creator\\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\\n}\\n\",\"keccak256\":\"0x621ac01b122e55554c87437ca7f64f571c18b43d100e2d2205ca06e9ae72a464\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b614f1480620000f36000396000f3fe608060405234801561001057600080fd5b506004361061031f5760003560e01c80638082f110116101a7578063bb7fde71116100ee578063da74222811610097578063f5298aca11610071578063f5298aca146107ee578063fd90e89714610801578063fdda1d0e1461082157600080fd5b8063da7422281461078c578063e985e9c51461079f578063f242432a146107db57600080fd5b8063ce1b815f116100c8578063ce1b815f1461073b578063d539139314610752578063d547741f1461077957600080fd5b8063bb7fde71146106f2578063bd85b03914610705578063befa66451461072657600080fd5b8063a217fddf11610150578063a55784ef1161012a578063a55784ef146106a0578063abe39603146106b3578063ac4a0fb6146106df57600080fd5b8063a217fddf14610672578063a22cb4651461067a578063a30b4db91461068d57600080fd5b8063933f395811610181578063933f39581461063a5780639a1b2fb41461064d5780639d28fb861461065f57600080fd5b80638082f110146105c457806381de2dc2146105ee57806391d148541461060157600080fd5b806336568abe1161026b57806350c821b0116102145780636b20c454116101ee5780636b20c45414610577578063791459ea1461058a578063797669c91461059d57600080fd5b806350c821b01461053157806355f804b314610551578063572b6c051461056457600080fd5b80634f124995116102455780634f124995146104e85780634f558e79146104fb5780635055fbc31461051e57600080fd5b806336568abe146104905780634e1273f4146104a35780634f062c5a146104c357600080fd5b8063248a9ca3116102cd5780632a55205a116102a75780632a55205a146104385780632eb2c2d61461046a5780632f2ff15d1461047d57600080fd5b8063248a9ca3146103c8578063282c51f3146103eb5780632a41a3551461041257600080fd5b8063124d91e5116102fe578063124d91e51461038d578063162094c4146103a257806320820ec3146103b557600080fd5b8062fdd58e1461032457806301ffc9a71461034a5780630e89341c1461036d575b600080fd5b610337610332366004613f5d565b610834565b6040519081526020015b60405180910390f35b61035d610358366004613f9f565b6108e2565b6040519015158152602001610341565b61038061037b366004613fbc565b610920565b6040516103419190614025565b6103a061039b366004614038565b61092b565b005b6103a06103b036600461414a565b610966565b6103a06103c3366004614226565b61099f565b6103376103d6366004613fbc565b600090815260fa602052604090206001015490565b6103377f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b610425610420366004613fbc565b6109d4565b60405161ffff9091168152602001610341565b61044b61044636600461429c565b6109e4565b604080516001600160a01b039093168352602083019190915201610341565b6103a06104783660046142be565b610b06565b6103a061048b36600461436c565b610c38565b6103a061049e36600461436c565b610c5d565b6104b66104b136600461439c565b610cf9565b604051610341919061449a565b6104d66104d1366004613fbc565b610e37565b60405160ff9091168152602001610341565b6103a06104f63660046144ad565b610e46565b61035d610509366004613fbc565b600090815261012c6020526040902054151590565b61035d61052c366004613fbc565b610e5c565b610539610e67565b6040516001600160a01b039091168152602001610341565b6103a061055f3660046144ef565b610e81565b61035d610572366004614524565b610e95565b6103a0610585366004614226565b610eb2565b6103a061059836600461454f565b610f5d565b6103377f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f81565b6105396105d2366004613fbc565b60009081526101c360205260409020546001600160a01b031690565b6104256105fc366004613fbc565b610fc8565b61035d61060f36600461436c565b600091825260fa602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61035d610648366004613fbc565b610fd8565b6101c2546001600160a01b0316610539565b6103a061066d366004614524565b610fe9565b610337600081565b6103a061068836600461454f565b611053565b61053961069b366004613fbc565b611154565b6103a06106ae36600461457d565b61115c565b6103376106c13660046144ef565b80516020818301810180516101f48252928201919093012091525481565b6103a06106ed366004614695565b611305565b6103a061070036600461471f565b61146a565b610337610713366004613fbc565b600090815261012c602052604090205490565b61072e6114c5565b6040516103419190614782565b6000546201000090046001600160a01b0316610539565b6103377f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6103a061078736600461436c565b6116df565b6103a061079a366004614524565b611704565b61035d6107ad3660046147cf565b6001600160a01b03918216600090815260976020908152604080832093909416825291909152205460ff1690565b6103a06107e93660046147fd565b61176e565b6103a06107fc366004614038565b611987565b61081461080f366004613fbc565b611a32565b6040516103419190614866565b61033761082f3660046144ef565b611bd4565b60006001600160a01b0383166108b75760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e65720000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526096602090815260408083206001600160a01b03861684529091529020545b92915050565b60006001600160e01b031982167fa30b4db90000000000000000000000000000000000000000000000000000000014806108dc57506108dc82611bfd565b60606108dc82611ca3565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84861095581611d85565b610960848484611d99565b50505050565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f61099081611d85565b61099a8383611f70565b505050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486109c981611d85565b610960848484611fce565b60006108dc8260b81c61ffff1690565b6000806000806101c260009054906101000a90046001600160a01b03166001600160a01b031663a86a28d16040518163ffffffff1660e01b81526004016040805180830381865afa158015610a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6191906148d9565b60008881526101c3602052604090205491935091506001600160a01b031615610ac35760008681526101c360205260409020546001600160a01b0316612710610aae61ffff841688614924565b610ab8919061493b565b935093505050610aff565b6001600160a01b03821615801590610ade575061ffff811615155b15610af55781612710610aae61ffff841688614924565b6000809350935050505b9250929050565b6101905485906001600160a01b03163b15610c2357610b23612260565b6001600160a01b0316816001600160a01b031603610b4d57610b48868686868661226a565b610c30565b610190546001600160a01b031663c617113430610b68612260565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd7919061495d565b610c235760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016108ae565b610c30868686868661226a565b505050505050565b600082815260fa6020526040902060010154610c5381611d85565b61099a838361231e565b610c65612260565b6001600160a01b0316816001600160a01b031614610ceb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016108ae565b610cf582826123c1565b5050565b60608151835114610d725760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016108ae565b6000835167ffffffffffffffff811115610d8e57610d8e61406d565b604051908082528060200260200182016040528015610db7578160200160208202803683370190505b50905060005b8451811015610e2f57610e02858281518110610ddb57610ddb61497a565b6020026020010151858381518110610df557610df561497a565b6020026020010151610834565b828281518110610e1457610e1461497a565b6020908102919091010152610e2881614990565b9050610dbd565b509392505050565b60006108dc8260a01c60ff1690565b6000610e5181611d85565b610960848484612462565b60006108dc82612587565b6000610e7c610190546001600160a01b031690565b905090565b6000610e8c81611d85565b610cf5826125a5565b600080546001600160a01b038381166201000090920416146108dc565b610eba612260565b6001600160a01b0316836001600160a01b03161480610ee05750610ee0836107ad612260565b610f525760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016108ae565b61099a838383611fce565b6000610f6881611d85565b6001600160a01b038316610fbe5760405162461bcd60e51b815260206004820152601360248201527f41737365743a205a65726f20616464726573730000000000000000000000000060448201526064016108ae565b61099a83836125b2565b60006108dc8260a81c61ffff1690565b6000600160c883901c8116146108dc565b6000610ff481611d85565b6001600160a01b03821661104a5760405162461bcd60e51b815260206004820152601360248201527f41737365743a205a65726f20616464726573730000000000000000000000000060448201526064016108ae565b610cf58261277e565b6101905482906001600160a01b03163b1561114257610190546040517fc61711340000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0383811660248301529091169063c617113490604401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f6919061495d565b6111425760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016108ae565b61099a61114d612260565b84846127d6565b6000816108dc565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661118681611d85565b81518451146111d75760405162461bcd60e51b815260206004820152601760248201527f41737365743a20312d4172726179206d69736d6174636800000000000000000060448201526064016108ae565b82518451146112285760405162461bcd60e51b815260206004820152601760248201527f41737365743a20322d4172726179206d69736d6174636800000000000000000060448201526064016108ae565b60005b8451811015611282576112708582815181106112495761124961497a565b60200260200101518483815181106112635761126361497a565b60200260200101516128ca565b8061127a81614990565b91505061122b565b5061129e8585856040518060200160405280600081525061298b565b60005b8451811015610c305760006112cc8683815181106112c1576112c161497a565b602002602001015190565b90506112f28683815181106112e3576112e361497a565b60200260200101518283612462565b50806112fd81614990565b9150506112a1565b600054610100900460ff16158080156113255750600054600160ff909116105b8061133f5750303b15801561133f575060005460ff166001145b6113b15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016108ae565b6000805460ff1916600117905580156113d4576000805461ff0019166101001790555b6113dd846125a5565b6113e5612b88565b6113ed612b88565b6113f686612bf5565b6113fe612b88565b61140960008661231e565b611414836001612c69565b61141d82612d0c565b8015610c30576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661149481611d85565b61149e84836128ca565b6114b985858560405180602001604052806000815250612d88565b83610c30818080612462565b6101c4546101c254604080517fa86a28d10000000000000000000000000000000000000000000000000000000081528151606094600094909385936001600160a01b039092169263a86a28d19260048082019392918290030181865afa158015611533573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155791906148d9565b5090506001600160a01b038116156115fc576101c4546115789060016149aa565b67ffffffffffffffff8111156115905761159061406d565b6040519080825280602002602001820160405280156115b9578160200160208202803683370190505b50935080846000815181106115d0576115d061497a565b6001600160a01b0390921660209283029190910190910152600192506115f582614990565b9150611645565b6101c45467ffffffffffffffff8111156116185761161861406d565b604051908082528060200260200182016040528015611641578160200160208202803683370190505b5093505b825b828110156116d8576101c360006101c461166187856149bd565b815481106116715761167161497a565b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b03168582815181106116b0576116b061497a565b6001600160a01b03909216602092830291909101909101526116d181614990565b9050611647565b5050505090565b600082815260fa60205260409020600101546116fa81611d85565b61099a83836123c1565b600061170f81611d85565b6001600160a01b0382166117655760405162461bcd60e51b815260206004820152601360248201527f41737365743a205a65726f20616464726573730000000000000000000000000060448201526064016108ae565b610cf582612ecb565b6101905485906001600160a01b03163b156119005761178b612260565b6001600160a01b0316816001600160a01b03160361182a576117ab612260565b6001600160a01b0316866001600160a01b031614806117d157506117d1866107ad612260565b61181d5760405162461bcd60e51b815260206004820152601560248201527f41737365743a205472616e73666572206572726f72000000000000000000000060448201526064016108ae565b610b488686868686612fe0565b610190546001600160a01b031663c617113430611845612260565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611890573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b4919061495d565b6119005760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016108ae565b611908612260565b6001600160a01b0316866001600160a01b0316148061192e575061192e866107ad612260565b61197a5760405162461bcd60e51b815260206004820152601560248201527f41737365743a205472616e73666572206572726f72000000000000000000000060448201526064016108ae565b610c308686868686612fe0565b61198f612260565b6001600160a01b0316836001600160a01b031614806119b557506119b5836107ad612260565b611a275760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016108ae565b61099a838383611d99565b60008181526101c36020526040808220546101c25482517fa86a28d100000000000000000000000000000000000000000000000000000000815283516060956001600160a01b039485169590949093169263a86a28d192600480820193918290030181865afa158015611aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611acd91906148d9565b5090506001600160a01b03821615611b4d57816001600160a01b031663d78d610b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b1d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b4591908101906149d0565b949350505050565b60408051600180825281830190925290816020015b6040805180820190915260008082526020820152815260200190600190039081611b625790505092506040518060400160405280826001600160a01b0316815260200161271061ffff1681525083600081518110611bc257611bc261497a565b60200260200101819052505050919050565b60006101f482604051611be79190614aa3565b9081526020016040518091039020549050919050565b60006001600160e01b031982167f2a55205a000000000000000000000000000000000000000000000000000000001480611c6057506001600160e01b031982167ff1e82fd000000000000000000000000000000000000000000000000000000000145b80611c9457506001600160e01b031982167ffd90e89700000000000000000000000000000000000000000000000000000000145b806108dc57506108dc826131d3565b600081815261015f6020526040812080546060929190611cc290614abf565b80601f0160208091040260200160405190810160405280929190818152602001828054611cee90614abf565b8015611d3b5780601f10611d1057610100808354040283529160200191611d3b565b820191906000526020600020905b815481529060010190602001808311611d1e57829003601f168201915b505050505090506000815111611d5957611d5483613211565b611d7e565b61015e81604051602001611d6e929190614af9565b6040516020818303038152906040525b9392505050565b611d9681611d91612260565b6132a5565b50565b6001600160a01b038316611e155760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000611e1f612260565b90506000611e2c8461331a565b90506000611e398461331a565b9050611e5983876000858560405180602001604052806000815250613365565b60008581526096602090815260408083206001600160a01b038a16845290915290205484811015611ef15760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016108ae565b60008681526096602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090525b50505050505050565b600082815261015f60205260409020611f898282614bc6565b50817f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b611fb584610920565b604051611fc29190614025565b60405180910390a25050565b6001600160a01b03831661204a5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b80518251146120ac5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016108ae565b60006120b6612260565b90506120d681856000868660405180602001604052806000815250613365565b60005b83518110156121f35760008482815181106120f6576120f661497a565b6020026020010151905060008483815181106121145761211461497a565b60209081029190910181015160008481526096835260408082206001600160a01b038c1683529093529190912054909150818110156121ba5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016108ae565b60009283526096602090815260408085206001600160a01b038b16865290915290922091039055806121eb81614990565b9150506120d9565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612244929190614c86565b60405180910390a4604080516020810190915260009052610960565b6000610e7c613373565b612272612260565b6001600160a01b0316856001600160a01b031614806122985750612298856107ad612260565b61230a5760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016108ae565b612317858585858561337d565b5050505050565b600082815260fa602090815260408083206001600160a01b038516845290915290205460ff16610cf557600082815260fa602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561237d612260565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260fa602090815260408083206001600160a01b038516845290915290205460ff1615610cf557600082815260fa602090815260408083206001600160a01b03851684529091529020805460ff1916905561241e612260565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6101c2546040517ff06040b40000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301528481166024830152600092169063f06040b4906044016020604051808303816000875af11580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190614cb4565b60008581526101c360205260409020549091506001600160a01b0316156125475760008481526101c360205260409020546001600160a01b0382811691161461254257612542848261361a565b610960565b6101c480546001810182556000919091527f5ac35dca7c3a7d5ae9d0add1efdc4aa02e10dd5cac0b90d2122cf0f0cc68317f01849055610960848261361a565b6000806125988360b81c61ffff1690565b61ffff1615159392505050565b61015e610cf58282614bc6565b610190546001600160a01b03163b15610cf557610190546040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b039091169063c3c5a547906024016020604051808303816000875af1158015612629573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264d919061495d565b610cf55780156126d357610190546040517f7d3e3dbe0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03848116602483015290911690637d3e3dbe906044015b600060405180830381600087803b1580156126bf57600080fd5b505af1158015610c30573d6000803e3d6000fd5b6001600160a01b0382161561273457610190546040517fa0af29030000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0384811660248301529091169063a0af2903906044016126a5565b610190546040517f4420e4860000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0390911690634420e486906024016126a5565b610190805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517fe9919957d871eafd2de063f58e6c3015bdee186c8a161b85d6173122db2210f890600090a250565b816001600160a01b0316836001600160a01b03160361285d5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016108ae565b6001600160a01b03838116600081815260976020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6101f4816040516128db9190614aa3565b90815260200160405180910390205460001461295f57816101f4826040516129039190614aa3565b90815260200160405180910390205414610cf55760405162461bcd60e51b815260206004820152601860248201527f41737365743a204861736820616c72656164792075736564000000000000000060448201526064016108ae565b816101f4826040516129719190614aa3565b90815260405190819003602001902055610cf58282611f70565b6001600160a01b038416612a075760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b8151835114612a695760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016108ae565b6000612a73612260565b9050612a8481600087878787613365565b60005b8451811015612b2057838181518110612aa257612aa261497a565b602002602001015160966000878481518110612ac057612ac061497a565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254612b0891906149aa565b90915550819050612b1881614990565b915050612a87565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612b71929190614c86565b60405180910390a46123178160008787878761368e565b600054610100900460ff16612bf35760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b565b600054610100900460ff16612c605760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b611d968161387a565b600054610100900460ff16612cd45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b610190805473ffffffffffffffffffffffffffffffffffffffff19166daaeb6d7670e522a718067333cd4e179055610cf582826125b2565b600054610100900460ff16612d775760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b612d80816138ee565b611d96612b88565b6001600160a01b038416612e045760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000612e0e612260565b90506000612e1b8561331a565b90506000612e288561331a565b9050612e3983600089858589613365565b60008681526096602090815260408083206001600160a01b038b16845290915281208054879290612e6b9084906149aa565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611f6783600089898989613946565b6000546001600160a01b0362010000909104811690821603612f555760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c7265616479207365740000000000000000000000000000000060648201526084016108ae565b612f5d612260565b600080546040516001600160a01b0393841693858116936201000090930416917f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e591a4600080546001600160a01b0390921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b6001600160a01b03841661305c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000613066612260565b905060006130738561331a565b905060006130808561331a565b9050613090838989858589613365565b60008681526096602090815260408083206001600160a01b038c168452909152902054858110156131295760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016108ae565b60008781526096602090815260408083206001600160a01b038d8116855292528083208985039055908a168252812080548892906131689084906149aa565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46131c8848a8a8a8a8a613946565b505050505050505050565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806108dc57506108dc82613a89565b60606098805461322090614abf565b80601f016020809104026020016040519081016040528092919081815260200182805461324c90614abf565b80156132995780601f1061326e57610100808354040283529160200191613299565b820191906000526020600020905b81548152906001019060200180831161327c57829003601f168201915b50505050509050919050565b600082815260fa602090815260408083206001600160a01b038516845290915290205460ff16610cf5576132d881613b24565b6132e3836020613b36565b6040516020016132f4929190614cd1565b60408051601f198184030181529082905262461bcd60e51b82526108ae91600401614025565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106133545761335461497a565b602090810291909101015292915050565b610c30868686868686613d5f565b6000610e7c613ef0565b81518351146133df5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016108ae565b6001600160a01b03841661345b5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000613465612260565b9050613475818787878787613365565b60005b84518110156135b45760008582815181106134955761349561497a565b6020026020010151905060008583815181106134b3576134b361497a565b60209081029190910181015160008481526096835260408082206001600160a01b038e16835290935291909120549091508181101561355a5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016108ae565b60008381526096602090815260408083206001600160a01b038e8116855292528083208585039055908b168252812080548492906135999084906149aa565b92505081905550505050806135ad90614990565b9050613478565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051613604929190614c86565b60405180910390a4610c3081878787878761368e565b60008281526101c36020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091558251858152918201527fe1684be972745471d95b80171bd593d7a1afd40c8d04f90bb29f27b78853918a910160405180910390a15050565b6001600160a01b0384163b15610c30576040517fbc197c810000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063bc197c81906136eb9089908990889088908890600401614d52565b6020604051808303816000875af1925050508015613726575060408051601f3d908101601f1916820190925261372391810190614da4565b60015b6137db57613732614dc1565b806308c379a00361376b5750613746614ddc565b80613751575061376d565b8060405162461bcd60e51b81526004016108ae9190614025565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016108ae565b6001600160e01b031981167fbc197c810000000000000000000000000000000000000000000000000000000014611f675760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016108ae565b600054610100900460ff166138e55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b611d9681612ecb565b6101c2805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de890600090a250565b6001600160a01b0384163b15610c30576040517ff23a6e610000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063f23a6e61906139a39089908990889088908890600401614e84565b6020604051808303816000875af19250505080156139de575060408051601f3d908101601f191682019092526139db91810190614da4565b60015b6139ea57613732614dc1565b6001600160e01b031981167ff23a6e610000000000000000000000000000000000000000000000000000000014611f675760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016108ae565b60006001600160e01b031982167fd9b67a26000000000000000000000000000000000000000000000000000000001480613aec57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b806108dc57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146108dc565b60606108dc6001600160a01b03831660145b60606000613b45836002614924565b613b509060026149aa565b67ffffffffffffffff811115613b6857613b6861406d565b6040519080825280601f01601f191660200182016040528015613b92576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110613bc957613bc961497a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613c2c57613c2c61497a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000613c68846002614924565b613c739060016149aa565b90505b6001811115613d10577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110613cb457613cb461497a565b1a60f81b828281518110613cca57613cca61497a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93613d0981614ec7565b9050613c76565b508315611d7e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ae565b6001600160a01b038516613de75760005b8351811015613de557828181518110613d8b57613d8b61497a565b602002602001015161012c6000868481518110613daa57613daa61497a565b602002602001015181526020019081526020016000206000828254613dcf91906149aa565b90915550613dde905081614990565b9050613d70565b505b6001600160a01b038416610c305760005b8351811015611f67576000848281518110613e1557613e1561497a565b602002602001015190506000848381518110613e3357613e3361497a565b60200260200101519050600061012c600084815260200190815260200160002054905081811015613ecc5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c7900000000000000000000000000000000000000000000000060648201526084016108ae565b600092835261012c602052604090922091039055613ee981614990565b9050613df8565b600080546201000090046001600160a01b031633148015613f12575060143610155b15613f4257507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b50335b90565b6001600160a01b0381168114611d9657600080fd5b60008060408385031215613f7057600080fd5b8235613f7b81613f48565b946020939093013593505050565b6001600160e01b031981168114611d9657600080fd5b600060208284031215613fb157600080fd5b8135611d7e81613f89565b600060208284031215613fce57600080fd5b5035919050565b60005b83811015613ff0578181015183820152602001613fd8565b50506000910152565b60008151808452614011816020860160208601613fd5565b601f01601f19169290920160200192915050565b602081526000611d7e6020830184613ff9565b60008060006060848603121561404d57600080fd5b833561405881613f48565b95602085013595506040909401359392505050565b634e487b7160e01b600052604160045260246000fd5b6040810181811067ffffffffffffffff821117156140a3576140a361406d565b60405250565b601f19601f830116810181811067ffffffffffffffff821117156140cf576140cf61406d565b6040525050565b600082601f8301126140e757600080fd5b813567ffffffffffffffff8111156141015761410161406d565b6040516141186020601f19601f85011601826140a9565b81815284602083860101111561412d57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561415d57600080fd5b82359150602083013567ffffffffffffffff81111561417b57600080fd5b614187858286016140d6565b9150509250929050565b600067ffffffffffffffff8211156141ab576141ab61406d565b5060051b60200190565b600082601f8301126141c657600080fd5b813560206141d382614191565b6040516141e082826140a9565b83815260059390931b850182019282810191508684111561420057600080fd5b8286015b8481101561421b5780358352918301918301614204565b509695505050505050565b60008060006060848603121561423b57600080fd5b833561424681613f48565b9250602084013567ffffffffffffffff8082111561426357600080fd5b61426f878388016141b5565b9350604086013591508082111561428557600080fd5b50614292868287016141b5565b9150509250925092565b600080604083850312156142af57600080fd5b50508035926020909101359150565b600080600080600060a086880312156142d657600080fd5b85356142e181613f48565b945060208601356142f181613f48565b9350604086013567ffffffffffffffff8082111561430e57600080fd5b61431a89838a016141b5565b9450606088013591508082111561433057600080fd5b61433c89838a016141b5565b9350608088013591508082111561435257600080fd5b5061435f888289016140d6565b9150509295509295909350565b6000806040838503121561437f57600080fd5b82359150602083013561439181613f48565b809150509250929050565b600080604083850312156143af57600080fd5b823567ffffffffffffffff808211156143c757600080fd5b818501915085601f8301126143db57600080fd5b813560206143e882614191565b6040516143f582826140a9565b83815260059390931b850182019282810191508984111561441557600080fd5b948201945b8386101561443c57853561442d81613f48565b8252948201949082019061441a565b9650508601359250508082111561445257600080fd5b50614187858286016141b5565b600081518084526020808501945080840160005b8381101561448f57815187529582019590820190600101614473565b509495945050505050565b602081526000611d7e602083018461445f565b6000806000606084860312156144c257600080fd5b8335925060208401356144d481613f48565b915060408401356144e481613f48565b809150509250925092565b60006020828403121561450157600080fd5b813567ffffffffffffffff81111561451857600080fd5b611b45848285016140d6565b60006020828403121561453657600080fd5b8135611d7e81613f48565b8015158114611d9657600080fd5b6000806040838503121561456257600080fd5b823561456d81613f48565b9150602083013561439181614541565b6000806000806080858703121561459357600080fd5b843561459e81613f48565b935060208581013567ffffffffffffffff808211156145bc57600080fd5b6145c889838a016141b5565b955060408801359150808211156145de57600080fd5b6145ea89838a016141b5565b9450606088013591508082111561460057600080fd5b818801915088601f83011261461457600080fd5b813561461f81614191565b60405161462c82826140a9565b82815260059290921b840185019185810191508b83111561464c57600080fd5b8585015b83811015614684578035858111156146685760008081fd5b6146768e89838a01016140d6565b845250918601918601614650565b50989b979a50959850505050505050565b600080600080600060a086880312156146ad57600080fd5b85356146b881613f48565b945060208601356146c881613f48565b9350604086013567ffffffffffffffff8111156146e457600080fd5b6146f0888289016140d6565b935050606086013561470181613f48565b9150608086013561471181613f48565b809150509295509295909350565b6000806000806080858703121561473557600080fd5b843561474081613f48565b93506020850135925060408501359150606085013567ffffffffffffffff81111561476a57600080fd5b614776878288016140d6565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156147c35783516001600160a01b03168352928401929184019160010161479e565b50909695505050505050565b600080604083850312156147e257600080fd5b82356147ed81613f48565b9150602083013561439181613f48565b600080600080600060a0868803121561481557600080fd5b853561482081613f48565b9450602086013561483081613f48565b93506040860135925060608601359150608086013567ffffffffffffffff81111561485a57600080fd5b61435f888289016140d6565b602080825282518282018190526000919060409081850190868401855b828110156148b557815180516001600160a01b0316855286015161ffff16868501529284019290850190600101614883565b5091979650505050505050565b805161ffff811681146148d457600080fd5b919050565b600080604083850312156148ec57600080fd5b82516148f781613f48565b9150614905602084016148c2565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176108dc576108dc61490e565b60008261495857634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561496f57600080fd5b8151611d7e81614541565b634e487b7160e01b600052603260045260246000fd5b600060001982036149a3576149a361490e565b5060010190565b808201808211156108dc576108dc61490e565b818103818111156108dc576108dc61490e565b600060208083850312156149e357600080fd5b825167ffffffffffffffff8111156149fa57600080fd5b8301601f81018513614a0b57600080fd5b8051614a1681614191565b60408051614a2483826140a9565b83815260069390931b8401850192858101925088841115614a4457600080fd5b938501935b83851015614a975781858a031215614a615760008081fd5b8151614a6c81614083565b8551614a7781613f48565b8152614a848688016148c2565b8188015283529381019391850191614a49565b98975050505050505050565b60008251614ab5818460208701613fd5565b9190910192915050565b600181811c90821680614ad357607f821691505b602082108103614af357634e487b7160e01b600052602260045260246000fd5b50919050565b6000808454614b0781614abf565b60018281168015614b1f5760018114614b3457614b63565b60ff1984168752821515830287019450614b63565b8860005260208060002060005b85811015614b5a5781548a820152908401908201614b41565b50505082870194505b505050508351614b77818360208801613fd5565b01949350505050565b601f82111561099a57600081815260208120601f850160051c81016020861015614ba75750805b601f850160051c820191505b81811015610c3057828155600101614bb3565b815167ffffffffffffffff811115614be057614be061406d565b614bf481614bee8454614abf565b84614b80565b602080601f831160018114614c295760008415614c115750858301515b600019600386901b1c1916600185901b178555610c30565b600085815260208120601f198616915b82811015614c5857888601518255948401946001909101908401614c39565b5085821015614c765787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000614c99604083018561445f565b8281036020840152614cab818561445f565b95945050505050565b600060208284031215614cc657600080fd5b8151611d7e81613f48565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614d09816017850160208801613fd5565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614d46816028840160208801613fd5565b01602801949350505050565b60006001600160a01b03808816835280871660208401525060a06040830152614d7e60a083018661445f565b8281036060840152614d90818661445f565b90508281036080840152614a978185613ff9565b600060208284031215614db657600080fd5b8151611d7e81613f89565b600060033d1115613f455760046000803e5060005160e01c90565b600060443d1015614dea5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715614e3857505050505090565b8285019150815181811115614e505750505050505090565b843d8701016020828501011115614e6a5750505050505090565b614e79602082860101876140a9565b509095945050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a06080830152614ebc60a0830184613ff9565b979650505050505050565b600081614ed657614ed661490e565b50600019019056fea26469706673582212202aba53a96b3924ff618826ec0b5434d0178e6166b760ce3977c6a0dbcebae92c64736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061031f5760003560e01c80638082f110116101a7578063bb7fde71116100ee578063da74222811610097578063f5298aca11610071578063f5298aca146107ee578063fd90e89714610801578063fdda1d0e1461082157600080fd5b8063da7422281461078c578063e985e9c51461079f578063f242432a146107db57600080fd5b8063ce1b815f116100c8578063ce1b815f1461073b578063d539139314610752578063d547741f1461077957600080fd5b8063bb7fde71146106f2578063bd85b03914610705578063befa66451461072657600080fd5b8063a217fddf11610150578063a55784ef1161012a578063a55784ef146106a0578063abe39603146106b3578063ac4a0fb6146106df57600080fd5b8063a217fddf14610672578063a22cb4651461067a578063a30b4db91461068d57600080fd5b8063933f395811610181578063933f39581461063a5780639a1b2fb41461064d5780639d28fb861461065f57600080fd5b80638082f110146105c457806381de2dc2146105ee57806391d148541461060157600080fd5b806336568abe1161026b57806350c821b0116102145780636b20c454116101ee5780636b20c45414610577578063791459ea1461058a578063797669c91461059d57600080fd5b806350c821b01461053157806355f804b314610551578063572b6c051461056457600080fd5b80634f124995116102455780634f124995146104e85780634f558e79146104fb5780635055fbc31461051e57600080fd5b806336568abe146104905780634e1273f4146104a35780634f062c5a146104c357600080fd5b8063248a9ca3116102cd5780632a55205a116102a75780632a55205a146104385780632eb2c2d61461046a5780632f2ff15d1461047d57600080fd5b8063248a9ca3146103c8578063282c51f3146103eb5780632a41a3551461041257600080fd5b8063124d91e5116102fe578063124d91e51461038d578063162094c4146103a257806320820ec3146103b557600080fd5b8062fdd58e1461032457806301ffc9a71461034a5780630e89341c1461036d575b600080fd5b610337610332366004613f5d565b610834565b6040519081526020015b60405180910390f35b61035d610358366004613f9f565b6108e2565b6040519015158152602001610341565b61038061037b366004613fbc565b610920565b6040516103419190614025565b6103a061039b366004614038565b61092b565b005b6103a06103b036600461414a565b610966565b6103a06103c3366004614226565b61099f565b6103376103d6366004613fbc565b600090815260fa602052604090206001015490565b6103377f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b610425610420366004613fbc565b6109d4565b60405161ffff9091168152602001610341565b61044b61044636600461429c565b6109e4565b604080516001600160a01b039093168352602083019190915201610341565b6103a06104783660046142be565b610b06565b6103a061048b36600461436c565b610c38565b6103a061049e36600461436c565b610c5d565b6104b66104b136600461439c565b610cf9565b604051610341919061449a565b6104d66104d1366004613fbc565b610e37565b60405160ff9091168152602001610341565b6103a06104f63660046144ad565b610e46565b61035d610509366004613fbc565b600090815261012c6020526040902054151590565b61035d61052c366004613fbc565b610e5c565b610539610e67565b6040516001600160a01b039091168152602001610341565b6103a061055f3660046144ef565b610e81565b61035d610572366004614524565b610e95565b6103a0610585366004614226565b610eb2565b6103a061059836600461454f565b610f5d565b6103377f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f81565b6105396105d2366004613fbc565b60009081526101c360205260409020546001600160a01b031690565b6104256105fc366004613fbc565b610fc8565b61035d61060f36600461436c565b600091825260fa602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61035d610648366004613fbc565b610fd8565b6101c2546001600160a01b0316610539565b6103a061066d366004614524565b610fe9565b610337600081565b6103a061068836600461454f565b611053565b61053961069b366004613fbc565b611154565b6103a06106ae36600461457d565b61115c565b6103376106c13660046144ef565b80516020818301810180516101f48252928201919093012091525481565b6103a06106ed366004614695565b611305565b6103a061070036600461471f565b61146a565b610337610713366004613fbc565b600090815261012c602052604090205490565b61072e6114c5565b6040516103419190614782565b6000546201000090046001600160a01b0316610539565b6103377f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6103a061078736600461436c565b6116df565b6103a061079a366004614524565b611704565b61035d6107ad3660046147cf565b6001600160a01b03918216600090815260976020908152604080832093909416825291909152205460ff1690565b6103a06107e93660046147fd565b61176e565b6103a06107fc366004614038565b611987565b61081461080f366004613fbc565b611a32565b6040516103419190614866565b61033761082f3660046144ef565b611bd4565b60006001600160a01b0383166108b75760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e65720000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526096602090815260408083206001600160a01b03861684529091529020545b92915050565b60006001600160e01b031982167fa30b4db90000000000000000000000000000000000000000000000000000000014806108dc57506108dc82611bfd565b60606108dc82611ca3565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84861095581611d85565b610960848484611d99565b50505050565b7f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f61099081611d85565b61099a8383611f70565b505050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486109c981611d85565b610960848484611fce565b60006108dc8260b81c61ffff1690565b6000806000806101c260009054906101000a90046001600160a01b03166001600160a01b031663a86a28d16040518163ffffffff1660e01b81526004016040805180830381865afa158015610a3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6191906148d9565b60008881526101c3602052604090205491935091506001600160a01b031615610ac35760008681526101c360205260409020546001600160a01b0316612710610aae61ffff841688614924565b610ab8919061493b565b935093505050610aff565b6001600160a01b03821615801590610ade575061ffff811615155b15610af55781612710610aae61ffff841688614924565b6000809350935050505b9250929050565b6101905485906001600160a01b03163b15610c2357610b23612260565b6001600160a01b0316816001600160a01b031603610b4d57610b48868686868661226a565b610c30565b610190546001600160a01b031663c617113430610b68612260565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610bb3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd7919061495d565b610c235760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016108ae565b610c30868686868661226a565b505050505050565b600082815260fa6020526040902060010154610c5381611d85565b61099a838361231e565b610c65612260565b6001600160a01b0316816001600160a01b031614610ceb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016108ae565b610cf582826123c1565b5050565b60608151835114610d725760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016108ae565b6000835167ffffffffffffffff811115610d8e57610d8e61406d565b604051908082528060200260200182016040528015610db7578160200160208202803683370190505b50905060005b8451811015610e2f57610e02858281518110610ddb57610ddb61497a565b6020026020010151858381518110610df557610df561497a565b6020026020010151610834565b828281518110610e1457610e1461497a565b6020908102919091010152610e2881614990565b9050610dbd565b509392505050565b60006108dc8260a01c60ff1690565b6000610e5181611d85565b610960848484612462565b60006108dc82612587565b6000610e7c610190546001600160a01b031690565b905090565b6000610e8c81611d85565b610cf5826125a5565b600080546001600160a01b038381166201000090920416146108dc565b610eba612260565b6001600160a01b0316836001600160a01b03161480610ee05750610ee0836107ad612260565b610f525760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016108ae565b61099a838383611fce565b6000610f6881611d85565b6001600160a01b038316610fbe5760405162461bcd60e51b815260206004820152601360248201527f41737365743a205a65726f20616464726573730000000000000000000000000060448201526064016108ae565b61099a83836125b2565b60006108dc8260a81c61ffff1690565b6000600160c883901c8116146108dc565b6000610ff481611d85565b6001600160a01b03821661104a5760405162461bcd60e51b815260206004820152601360248201527f41737365743a205a65726f20616464726573730000000000000000000000000060448201526064016108ae565b610cf58261277e565b6101905482906001600160a01b03163b1561114257610190546040517fc61711340000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0383811660248301529091169063c617113490604401602060405180830381865afa1580156110d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110f6919061495d565b6111425760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016108ae565b61099a61114d612260565b84846127d6565b6000816108dc565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661118681611d85565b81518451146111d75760405162461bcd60e51b815260206004820152601760248201527f41737365743a20312d4172726179206d69736d6174636800000000000000000060448201526064016108ae565b82518451146112285760405162461bcd60e51b815260206004820152601760248201527f41737365743a20322d4172726179206d69736d6174636800000000000000000060448201526064016108ae565b60005b8451811015611282576112708582815181106112495761124961497a565b60200260200101518483815181106112635761126361497a565b60200260200101516128ca565b8061127a81614990565b91505061122b565b5061129e8585856040518060200160405280600081525061298b565b60005b8451811015610c305760006112cc8683815181106112c1576112c161497a565b602002602001015190565b90506112f28683815181106112e3576112e361497a565b60200260200101518283612462565b50806112fd81614990565b9150506112a1565b600054610100900460ff16158080156113255750600054600160ff909116105b8061133f5750303b15801561133f575060005460ff166001145b6113b15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016108ae565b6000805460ff1916600117905580156113d4576000805461ff0019166101001790555b6113dd846125a5565b6113e5612b88565b6113ed612b88565b6113f686612bf5565b6113fe612b88565b61140960008661231e565b611414836001612c69565b61141d82612d0c565b8015610c30576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661149481611d85565b61149e84836128ca565b6114b985858560405180602001604052806000815250612d88565b83610c30818080612462565b6101c4546101c254604080517fa86a28d10000000000000000000000000000000000000000000000000000000081528151606094600094909385936001600160a01b039092169263a86a28d19260048082019392918290030181865afa158015611533573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155791906148d9565b5090506001600160a01b038116156115fc576101c4546115789060016149aa565b67ffffffffffffffff8111156115905761159061406d565b6040519080825280602002602001820160405280156115b9578160200160208202803683370190505b50935080846000815181106115d0576115d061497a565b6001600160a01b0390921660209283029190910190910152600192506115f582614990565b9150611645565b6101c45467ffffffffffffffff8111156116185761161861406d565b604051908082528060200260200182016040528015611641578160200160208202803683370190505b5093505b825b828110156116d8576101c360006101c461166187856149bd565b815481106116715761167161497a565b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b03168582815181106116b0576116b061497a565b6001600160a01b03909216602092830291909101909101526116d181614990565b9050611647565b5050505090565b600082815260fa60205260409020600101546116fa81611d85565b61099a83836123c1565b600061170f81611d85565b6001600160a01b0382166117655760405162461bcd60e51b815260206004820152601360248201527f41737365743a205a65726f20616464726573730000000000000000000000000060448201526064016108ae565b610cf582612ecb565b6101905485906001600160a01b03163b156119005761178b612260565b6001600160a01b0316816001600160a01b03160361182a576117ab612260565b6001600160a01b0316866001600160a01b031614806117d157506117d1866107ad612260565b61181d5760405162461bcd60e51b815260206004820152601560248201527f41737365743a205472616e73666572206572726f72000000000000000000000060448201526064016108ae565b610b488686868686612fe0565b610190546001600160a01b031663c617113430611845612260565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611890573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b4919061495d565b6119005760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016108ae565b611908612260565b6001600160a01b0316866001600160a01b0316148061192e575061192e866107ad612260565b61197a5760405162461bcd60e51b815260206004820152601560248201527f41737365743a205472616e73666572206572726f72000000000000000000000060448201526064016108ae565b610c308686868686612fe0565b61198f612260565b6001600160a01b0316836001600160a01b031614806119b557506119b5836107ad612260565b611a275760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016108ae565b61099a838383611d99565b60008181526101c36020526040808220546101c25482517fa86a28d100000000000000000000000000000000000000000000000000000000815283516060956001600160a01b039485169590949093169263a86a28d192600480820193918290030181865afa158015611aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611acd91906148d9565b5090506001600160a01b03821615611b4d57816001600160a01b031663d78d610b6040518163ffffffff1660e01b8152600401600060405180830381865afa158015611b1d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611b4591908101906149d0565b949350505050565b60408051600180825281830190925290816020015b6040805180820190915260008082526020820152815260200190600190039081611b625790505092506040518060400160405280826001600160a01b0316815260200161271061ffff1681525083600081518110611bc257611bc261497a565b60200260200101819052505050919050565b60006101f482604051611be79190614aa3565b9081526020016040518091039020549050919050565b60006001600160e01b031982167f2a55205a000000000000000000000000000000000000000000000000000000001480611c6057506001600160e01b031982167ff1e82fd000000000000000000000000000000000000000000000000000000000145b80611c9457506001600160e01b031982167ffd90e89700000000000000000000000000000000000000000000000000000000145b806108dc57506108dc826131d3565b600081815261015f6020526040812080546060929190611cc290614abf565b80601f0160208091040260200160405190810160405280929190818152602001828054611cee90614abf565b8015611d3b5780601f10611d1057610100808354040283529160200191611d3b565b820191906000526020600020905b815481529060010190602001808311611d1e57829003601f168201915b505050505090506000815111611d5957611d5483613211565b611d7e565b61015e81604051602001611d6e929190614af9565b6040516020818303038152906040525b9392505050565b611d9681611d91612260565b6132a5565b50565b6001600160a01b038316611e155760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000611e1f612260565b90506000611e2c8461331a565b90506000611e398461331a565b9050611e5983876000858560405180602001604052806000815250613365565b60008581526096602090815260408083206001600160a01b038a16845290915290205484811015611ef15760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016108ae565b60008681526096602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090525b50505050505050565b600082815261015f60205260409020611f898282614bc6565b50817f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b611fb584610920565b604051611fc29190614025565b60405180910390a25050565b6001600160a01b03831661204a5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b80518251146120ac5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016108ae565b60006120b6612260565b90506120d681856000868660405180602001604052806000815250613365565b60005b83518110156121f35760008482815181106120f6576120f661497a565b6020026020010151905060008483815181106121145761211461497a565b60209081029190910181015160008481526096835260408082206001600160a01b038c1683529093529190912054909150818110156121ba5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016108ae565b60009283526096602090815260408085206001600160a01b038b16865290915290922091039055806121eb81614990565b9150506120d9565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051612244929190614c86565b60405180910390a4604080516020810190915260009052610960565b6000610e7c613373565b612272612260565b6001600160a01b0316856001600160a01b031614806122985750612298856107ad612260565b61230a5760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016108ae565b612317858585858561337d565b5050505050565b600082815260fa602090815260408083206001600160a01b038516845290915290205460ff16610cf557600082815260fa602090815260408083206001600160a01b03851684529091529020805460ff1916600117905561237d612260565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260fa602090815260408083206001600160a01b038516845290915290205460ff1615610cf557600082815260fa602090815260408083206001600160a01b03851684529091529020805460ff1916905561241e612260565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6101c2546040517ff06040b40000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301528481166024830152600092169063f06040b4906044016020604051808303816000875af11580156124d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124f59190614cb4565b60008581526101c360205260409020549091506001600160a01b0316156125475760008481526101c360205260409020546001600160a01b0382811691161461254257612542848261361a565b610960565b6101c480546001810182556000919091527f5ac35dca7c3a7d5ae9d0add1efdc4aa02e10dd5cac0b90d2122cf0f0cc68317f01849055610960848261361a565b6000806125988360b81c61ffff1690565b61ffff1615159392505050565b61015e610cf58282614bc6565b610190546001600160a01b03163b15610cf557610190546040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b039091169063c3c5a547906024016020604051808303816000875af1158015612629573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264d919061495d565b610cf55780156126d357610190546040517f7d3e3dbe0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03848116602483015290911690637d3e3dbe906044015b600060405180830381600087803b1580156126bf57600080fd5b505af1158015610c30573d6000803e3d6000fd5b6001600160a01b0382161561273457610190546040517fa0af29030000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0384811660248301529091169063a0af2903906044016126a5565b610190546040517f4420e4860000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0390911690634420e486906024016126a5565b610190805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517fe9919957d871eafd2de063f58e6c3015bdee186c8a161b85d6173122db2210f890600090a250565b816001600160a01b0316836001600160a01b03160361285d5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016108ae565b6001600160a01b03838116600081815260976020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6101f4816040516128db9190614aa3565b90815260200160405180910390205460001461295f57816101f4826040516129039190614aa3565b90815260200160405180910390205414610cf55760405162461bcd60e51b815260206004820152601860248201527f41737365743a204861736820616c72656164792075736564000000000000000060448201526064016108ae565b816101f4826040516129719190614aa3565b90815260405190819003602001902055610cf58282611f70565b6001600160a01b038416612a075760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b8151835114612a695760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016108ae565b6000612a73612260565b9050612a8481600087878787613365565b60005b8451811015612b2057838181518110612aa257612aa261497a565b602002602001015160966000878481518110612ac057612ac061497a565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254612b0891906149aa565b90915550819050612b1881614990565b915050612a87565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612b71929190614c86565b60405180910390a46123178160008787878761368e565b600054610100900460ff16612bf35760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b565b600054610100900460ff16612c605760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b611d968161387a565b600054610100900460ff16612cd45760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b610190805473ffffffffffffffffffffffffffffffffffffffff19166daaeb6d7670e522a718067333cd4e179055610cf582826125b2565b600054610100900460ff16612d775760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b612d80816138ee565b611d96612b88565b6001600160a01b038416612e045760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000612e0e612260565b90506000612e1b8561331a565b90506000612e288561331a565b9050612e3983600089858589613365565b60008681526096602090815260408083206001600160a01b038b16845290915281208054879290612e6b9084906149aa565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611f6783600089898989613946565b6000546001600160a01b0362010000909104811690821603612f555760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c7265616479207365740000000000000000000000000000000060648201526084016108ae565b612f5d612260565b600080546040516001600160a01b0393841693858116936201000090930416917f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e591a4600080546001600160a01b0390921662010000027fffffffffffffffffffff0000000000000000000000000000000000000000ffff909216919091179055565b6001600160a01b03841661305c5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000613066612260565b905060006130738561331a565b905060006130808561331a565b9050613090838989858589613365565b60008681526096602090815260408083206001600160a01b038c168452909152902054858110156131295760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016108ae565b60008781526096602090815260408083206001600160a01b038d8116855292528083208985039055908a168252812080548892906131689084906149aa565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46131c8848a8a8a8a8a613946565b505050505050505050565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806108dc57506108dc82613a89565b60606098805461322090614abf565b80601f016020809104026020016040519081016040528092919081815260200182805461324c90614abf565b80156132995780601f1061326e57610100808354040283529160200191613299565b820191906000526020600020905b81548152906001019060200180831161327c57829003601f168201915b50505050509050919050565b600082815260fa602090815260408083206001600160a01b038516845290915290205460ff16610cf5576132d881613b24565b6132e3836020613b36565b6040516020016132f4929190614cd1565b60408051601f198184030181529082905262461bcd60e51b82526108ae91600401614025565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106133545761335461497a565b602090810291909101015292915050565b610c30868686868686613d5f565b6000610e7c613ef0565b81518351146133df5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016108ae565b6001600160a01b03841661345b5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016108ae565b6000613465612260565b9050613475818787878787613365565b60005b84518110156135b45760008582815181106134955761349561497a565b6020026020010151905060008583815181106134b3576134b361497a565b60209081029190910181015160008481526096835260408082206001600160a01b038e16835290935291909120549091508181101561355a5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016108ae565b60008381526096602090815260408083206001600160a01b038e8116855292528083208585039055908b168252812080548492906135999084906149aa565b92505081905550505050806135ad90614990565b9050613478565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051613604929190614c86565b60405180910390a4610c3081878787878761368e565b60008281526101c36020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091558251858152918201527fe1684be972745471d95b80171bd593d7a1afd40c8d04f90bb29f27b78853918a910160405180910390a15050565b6001600160a01b0384163b15610c30576040517fbc197c810000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063bc197c81906136eb9089908990889088908890600401614d52565b6020604051808303816000875af1925050508015613726575060408051601f3d908101601f1916820190925261372391810190614da4565b60015b6137db57613732614dc1565b806308c379a00361376b5750613746614ddc565b80613751575061376d565b8060405162461bcd60e51b81526004016108ae9190614025565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016108ae565b6001600160e01b031981167fbc197c810000000000000000000000000000000000000000000000000000000014611f675760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016108ae565b600054610100900460ff166138e55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016108ae565b611d9681612ecb565b6101c2805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de890600090a250565b6001600160a01b0384163b15610c30576040517ff23a6e610000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063f23a6e61906139a39089908990889088908890600401614e84565b6020604051808303816000875af19250505080156139de575060408051601f3d908101601f191682019092526139db91810190614da4565b60015b6139ea57613732614dc1565b6001600160e01b031981167ff23a6e610000000000000000000000000000000000000000000000000000000014611f675760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016108ae565b60006001600160e01b031982167fd9b67a26000000000000000000000000000000000000000000000000000000001480613aec57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b806108dc57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146108dc565b60606108dc6001600160a01b03831660145b60606000613b45836002614924565b613b509060026149aa565b67ffffffffffffffff811115613b6857613b6861406d565b6040519080825280601f01601f191660200182016040528015613b92576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110613bc957613bc961497a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613c2c57613c2c61497a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000613c68846002614924565b613c739060016149aa565b90505b6001811115613d10577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110613cb457613cb461497a565b1a60f81b828281518110613cca57613cca61497a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93613d0981614ec7565b9050613c76565b508315611d7e5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ae565b6001600160a01b038516613de75760005b8351811015613de557828181518110613d8b57613d8b61497a565b602002602001015161012c6000868481518110613daa57613daa61497a565b602002602001015181526020019081526020016000206000828254613dcf91906149aa565b90915550613dde905081614990565b9050613d70565b505b6001600160a01b038416610c305760005b8351811015611f67576000848281518110613e1557613e1561497a565b602002602001015190506000848381518110613e3357613e3361497a565b60200260200101519050600061012c600084815260200190815260200160002054905081811015613ecc5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c7900000000000000000000000000000000000000000000000060648201526084016108ae565b600092835261012c602052604090922091039055613ee981614990565b9050613df8565b600080546201000090046001600160a01b031633148015613f12575060143610155b15613f4257507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b50335b90565b6001600160a01b0381168114611d9657600080fd5b60008060408385031215613f7057600080fd5b8235613f7b81613f48565b946020939093013593505050565b6001600160e01b031981168114611d9657600080fd5b600060208284031215613fb157600080fd5b8135611d7e81613f89565b600060208284031215613fce57600080fd5b5035919050565b60005b83811015613ff0578181015183820152602001613fd8565b50506000910152565b60008151808452614011816020860160208601613fd5565b601f01601f19169290920160200192915050565b602081526000611d7e6020830184613ff9565b60008060006060848603121561404d57600080fd5b833561405881613f48565b95602085013595506040909401359392505050565b634e487b7160e01b600052604160045260246000fd5b6040810181811067ffffffffffffffff821117156140a3576140a361406d565b60405250565b601f19601f830116810181811067ffffffffffffffff821117156140cf576140cf61406d565b6040525050565b600082601f8301126140e757600080fd5b813567ffffffffffffffff8111156141015761410161406d565b6040516141186020601f19601f85011601826140a9565b81815284602083860101111561412d57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806040838503121561415d57600080fd5b82359150602083013567ffffffffffffffff81111561417b57600080fd5b614187858286016140d6565b9150509250929050565b600067ffffffffffffffff8211156141ab576141ab61406d565b5060051b60200190565b600082601f8301126141c657600080fd5b813560206141d382614191565b6040516141e082826140a9565b83815260059390931b850182019282810191508684111561420057600080fd5b8286015b8481101561421b5780358352918301918301614204565b509695505050505050565b60008060006060848603121561423b57600080fd5b833561424681613f48565b9250602084013567ffffffffffffffff8082111561426357600080fd5b61426f878388016141b5565b9350604086013591508082111561428557600080fd5b50614292868287016141b5565b9150509250925092565b600080604083850312156142af57600080fd5b50508035926020909101359150565b600080600080600060a086880312156142d657600080fd5b85356142e181613f48565b945060208601356142f181613f48565b9350604086013567ffffffffffffffff8082111561430e57600080fd5b61431a89838a016141b5565b9450606088013591508082111561433057600080fd5b61433c89838a016141b5565b9350608088013591508082111561435257600080fd5b5061435f888289016140d6565b9150509295509295909350565b6000806040838503121561437f57600080fd5b82359150602083013561439181613f48565b809150509250929050565b600080604083850312156143af57600080fd5b823567ffffffffffffffff808211156143c757600080fd5b818501915085601f8301126143db57600080fd5b813560206143e882614191565b6040516143f582826140a9565b83815260059390931b850182019282810191508984111561441557600080fd5b948201945b8386101561443c57853561442d81613f48565b8252948201949082019061441a565b9650508601359250508082111561445257600080fd5b50614187858286016141b5565b600081518084526020808501945080840160005b8381101561448f57815187529582019590820190600101614473565b509495945050505050565b602081526000611d7e602083018461445f565b6000806000606084860312156144c257600080fd5b8335925060208401356144d481613f48565b915060408401356144e481613f48565b809150509250925092565b60006020828403121561450157600080fd5b813567ffffffffffffffff81111561451857600080fd5b611b45848285016140d6565b60006020828403121561453657600080fd5b8135611d7e81613f48565b8015158114611d9657600080fd5b6000806040838503121561456257600080fd5b823561456d81613f48565b9150602083013561439181614541565b6000806000806080858703121561459357600080fd5b843561459e81613f48565b935060208581013567ffffffffffffffff808211156145bc57600080fd5b6145c889838a016141b5565b955060408801359150808211156145de57600080fd5b6145ea89838a016141b5565b9450606088013591508082111561460057600080fd5b818801915088601f83011261461457600080fd5b813561461f81614191565b60405161462c82826140a9565b82815260059290921b840185019185810191508b83111561464c57600080fd5b8585015b83811015614684578035858111156146685760008081fd5b6146768e89838a01016140d6565b845250918601918601614650565b50989b979a50959850505050505050565b600080600080600060a086880312156146ad57600080fd5b85356146b881613f48565b945060208601356146c881613f48565b9350604086013567ffffffffffffffff8111156146e457600080fd5b6146f0888289016140d6565b935050606086013561470181613f48565b9150608086013561471181613f48565b809150509295509295909350565b6000806000806080858703121561473557600080fd5b843561474081613f48565b93506020850135925060408501359150606085013567ffffffffffffffff81111561476a57600080fd5b614776878288016140d6565b91505092959194509250565b6020808252825182820181905260009190848201906040850190845b818110156147c35783516001600160a01b03168352928401929184019160010161479e565b50909695505050505050565b600080604083850312156147e257600080fd5b82356147ed81613f48565b9150602083013561439181613f48565b600080600080600060a0868803121561481557600080fd5b853561482081613f48565b9450602086013561483081613f48565b93506040860135925060608601359150608086013567ffffffffffffffff81111561485a57600080fd5b61435f888289016140d6565b602080825282518282018190526000919060409081850190868401855b828110156148b557815180516001600160a01b0316855286015161ffff16868501529284019290850190600101614883565b5091979650505050505050565b805161ffff811681146148d457600080fd5b919050565b600080604083850312156148ec57600080fd5b82516148f781613f48565b9150614905602084016148c2565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176108dc576108dc61490e565b60008261495857634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561496f57600080fd5b8151611d7e81614541565b634e487b7160e01b600052603260045260246000fd5b600060001982036149a3576149a361490e565b5060010190565b808201808211156108dc576108dc61490e565b818103818111156108dc576108dc61490e565b600060208083850312156149e357600080fd5b825167ffffffffffffffff8111156149fa57600080fd5b8301601f81018513614a0b57600080fd5b8051614a1681614191565b60408051614a2483826140a9565b83815260069390931b8401850192858101925088841115614a4457600080fd5b938501935b83851015614a975781858a031215614a615760008081fd5b8151614a6c81614083565b8551614a7781613f48565b8152614a848688016148c2565b8188015283529381019391850191614a49565b98975050505050505050565b60008251614ab5818460208701613fd5565b9190910192915050565b600181811c90821680614ad357607f821691505b602082108103614af357634e487b7160e01b600052602260045260246000fd5b50919050565b6000808454614b0781614abf565b60018281168015614b1f5760018114614b3457614b63565b60ff1984168752821515830287019450614b63565b8860005260208060002060005b85811015614b5a5781548a820152908401908201614b41565b50505082870194505b505050508351614b77818360208801613fd5565b01949350505050565b601f82111561099a57600081815260208120601f850160051c81016020861015614ba75750805b601f850160051c820191505b81811015610c3057828155600101614bb3565b815167ffffffffffffffff811115614be057614be061406d565b614bf481614bee8454614abf565b84614b80565b602080601f831160018114614c295760008415614c115750858301515b600019600386901b1c1916600185901b178555610c30565b600085815260208120601f198616915b82811015614c5857888601518255948401946001909101908401614c39565b5085821015614c765787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b604081526000614c99604083018561445f565b8281036020840152614cab818561445f565b95945050505050565b600060208284031215614cc657600080fd5b8151611d7e81613f48565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614d09816017850160208801613fd5565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614d46816028840160208801613fd5565b01602801949350505050565b60006001600160a01b03808816835280871660208401525060a06040830152614d7e60a083018661445f565b8281036060840152614d90818661445f565b90508281036080840152614a978185613ff9565b600060208284031215614db657600080fd5b8151611d7e81613f89565b600060033d1115613f455760046000803e5060005160e01c90565b600060443d1015614dea5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715614e3857505050505090565b8285019150815181811115614e505750505050505090565b843d8701016020828501011115614e6a5750505050505090565b614e79602082860101876140a9565b509095945050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a06080830152614ebc60a0830184613ff9565b979650505050505050565b600081614ed657614ed661490e565b50600019019056fea26469706673582212202aba53a96b3924ff618826ec0b5434d0178e6166b760ce3977c6a0dbcebae92c64736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "details": "This contract is final and should not be inherited", + "events": { + "ApprovalForAll(address,address,bool)": { + "details": "Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`." + }, + "Initialized(uint8)": { + "details": "Triggered when the contract has been initialized or reinitialized." + }, + "RoleAdminChanged(bytes32,bytes32,bytes32)": { + "details": "Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._" + }, + "RoleGranted(bytes32,address,address)": { + "details": "Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}." + }, + "RoleRevoked(bytes32,address,address)": { + "details": "Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)" + }, + "TransferBatch(address,address,address,uint256[],uint256[])": { + "details": "Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all transfers." + }, + "TransferSingle(address,address,address,uint256,uint256)": { + "details": "Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`." + }, + "TrustedForwarderSet(address,address,address)": { + "params": { + "newTrustedForwarder": "new trusted forwarder", + "oldTrustedForwarder": "old trusted forwarder", + "operator": "the sender of the transaction" + } + }, + "URI(string,uint256)": { + "details": "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}." + } + }, + "kind": "dev", + "methods": { + "balanceOf(address,uint256)": { + "details": "See {IERC1155-balanceOf}. Requirements: - `account` cannot be the zero address." + }, + "balanceOfBatch(address[],uint256[])": { + "details": "See {IERC1155-balanceOfBatch}. Requirements: - `accounts` and `ids` must have the same length." + }, + "burnBatchFrom(address,uint256[],uint256[])": { + "details": "Only the minter role can burn tokensThis function was added with token recycling and bridging in mind but may have other use casesThe length of the ids and amounts arrays must be the same", + "params": { + "account": "The account to burn tokens from", + "amounts": "An array of amounts of tokens to burn", + "ids": "An array of token ids to burn" + } + }, + "burnFrom(address,uint256,uint256)": { + "details": "Only the minter role can burn tokensThis function was added with token recycling and bridging in mind but may have other use cases", + "params": { + "account": "The account to burn tokens from", + "amount": "The amount of tokens to burn", + "id": "The token id to burn" + } + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "exists(uint256)": { + "details": "Indicates whether any token exist with a given id, or not." + }, + "getAllSplits()": { + "returns": { + "splits": "the royalty receiver's array" + } + }, + "getCreatorAddress(uint256)": { + "params": { + "tokenId": "The token id to extract the creator address from" + }, + "returns": { + "creator": "The asset creator address" + } + }, + "getCreatorNonce(uint256)": { + "params": { + "tokenId": "The token id to extract the asset nonce from" + }, + "returns": { + "creatorNonce": "The asset creator nonce" + } + }, + "getOperatorFilterRegistry()": { + "returns": { + "operatorFilterRegistryAddress": "address of operator filter registry contract." + } + }, + "getRecipients(uint256)": { + "details": "returns the default address for tokens with no recipients.", + "params": { + "tokenId": "is the token id for which the recipient should be returned." + }, + "returns": { + "recipients": "array of royalty recipients for the token" + } + }, + "getRevealNonce(uint256)": { + "params": { + "tokenId": "The token id to extract reveal nonce from" + }, + "returns": { + "revealNonce": "The reveal nonce of the asset" + } + }, + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getRoyaltyManager()": { + "returns": { + "managerAddress": "address of royalty manager." + } + }, + "getTier(uint256)": { + "params": { + "tokenId": "The token id to extract the tier from" + }, + "returns": { + "tier": "The asset tier, determined by the catalyst used to create it" + } + }, + "getTokenIdByMetadataHash(string)": { + "params": { + "metadataHash": "The metadata hash to get tokenId for" + }, + "returns": { + "tokenId": "the tokenId associated with the metadata hash" + } + }, + "getTokenRoyaltiesSplitter(uint256)": { + "params": { + "tokenId": "is the token id for which royalty splitter should be returned." + }, + "returns": { + "splitterAddress": "address of royalty splitter for the token" + } + }, + "getTrustedForwarder()": { + "returns": { + "_0": "return the address of the trusted forwarder" + } + }, + "grantRole(bytes32,address)": { + "details": "Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event." + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "initialize(address,address,string,address,address)": { + "params": { + "_manager": "The address of the royalty manager", + "assetAdmin": "The address of the asset admin", + "baseUri": "The base URI for the token metadata", + "commonSubscription": "The address of the operator filter subscription", + "forwarder": "The address of the trusted forwarder" + } + }, + "isApprovedForAll(address,address)": { + "details": "See {IERC1155-isApprovedForAll}." + }, + "isBridged(uint256)": { + "params": { + "tokenId": "The token id to extract the bridged flag from" + }, + "returns": { + "bridged": "Whether the asset is bridged or not" + } + }, + "isRevealed(uint256)": { + "params": { + "tokenId": "The token id to extract the revealed flag from" + }, + "returns": { + "revealed": "Whether the asset is revealed or not" + } + }, + "isTrustedForwarder(address)": { + "params": { + "forwarder": "trusted forwarder address to check" + }, + "returns": { + "_0": "true if the address is the same as the trusted forwarder" + } + }, + "mint(address,uint256,uint256,string)": { + "details": "Only callable by the minter role", + "params": { + "amount": "The amount of the token to mint", + "id": "The id of the token to mint", + "metadataHash": "The metadata hash of the token to mint", + "to": "The address of the recipient" + } + }, + "mintBatch(address,uint256[],uint256[],string[])": { + "details": "Only callable by the minter role", + "params": { + "amounts": "The amounts of the tokens to mint", + "ids": "The ids of the tokens to mint", + "metadataHashes": "The metadata hashes of the tokens to mint", + "to": "The address of the recipient" + } + }, + "registerAndSubscribe(address,bool)": { + "details": "used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.", + "params": { + "subscribe": "bool to signify subscription \"true\"\" or to copy the list \"false\".", + "subscriptionOrRegistrantToCopy": "registration address of the list to subscribe." + } + }, + "renounceRole(bytes32,address)": { + "details": "Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event." + }, + "revokeRole(bytes32,address)": { + "details": "Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event." + }, + "royaltyInfo(uint256,uint256)": { + "params": { + "tokenId": "of the token for which the royalty is needed to be distributed", + "value": "the amount on which the royalty is calculated" + }, + "returns": { + "receiver": "address the royalty receiver", + "royaltyAmount": "value the EIP2981 royalty" + } + }, + "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)": { + "details": "call data should be optimized to order ids so packedBalance can be used efficiently.", + "params": { + "amounts": "amount of each token type transfered.", + "data": "additional data accompanying the transfer.", + "from": "address from which tokens are transfered.", + "ids": "ids of each token type transfered.", + "to": "address to which the token will be transfered." + } + }, + "safeTransferFrom(address,address,uint256,uint256,bytes)": { + "params": { + "amount": "amount of token transfered.", + "data": "additional data accompanying the transfer.", + "from": "address from which tokens are transfered.", + "id": "the token type transfered.", + "to": "address to which the token will be transfered." + } + }, + "setApprovalForAll(address,bool)": { + "params": { + "approved": "whether to approve or revoke", + "operator": "address which will be granted rights to transfer all tokens of the caller." + } + }, + "setBaseURI(string)": { + "params": { + "baseURI": "The new base URI" + } + }, + "setOperatorRegistry(address)": { + "params": { + "registry": "the address of the registry" + } + }, + "setTokenRoyalties(uint256,address,address)": { + "params": { + "creator": "the creator of the tokens.", + "recipient": "the royalty recipient for the splitter of the creator.", + "tokenId": "the id of the token for which the EIP2981 royalty is set for." + } + }, + "setTokenURI(uint256,string)": { + "details": "The metadata hash should be the IPFS CIDv1 base32 encoded hash", + "params": { + "metadata": "The new URI for asset's metadata", + "tokenId": "The token id to set URI for" + } + }, + "setTrustedForwarder(address)": { + "details": "Change the address of the trusted forwarder for meta-TX", + "params": { + "trustedForwarder": "The new trustedForwarder" + } + }, + "supportsInterface(bytes4)": { + "params": { + "id": "the interface identifier, as specified in ERC-165." + }, + "returns": { + "supported": "`true` if the contract implements `id`." + } + }, + "totalSupply(uint256)": { + "details": "Total amount of tokens in with a given id." + }, + "uri(uint256)": { + "params": { + "tokenId": "The token id to get URI for" + }, + "returns": { + "tokenURI": "the URI of the token" + } + } + }, + "title": "Asset", + "version": 1 + }, + "userdoc": { + "events": { + "TrustedForwarderSet(address,address,address)": { + "notice": "Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`" + } + }, + "kind": "user", + "methods": { + "burnBatchFrom(address,uint256[],uint256[])": { + "notice": "Burn a batch of tokens from a given account" + }, + "burnFrom(address,uint256,uint256)": { + "notice": "Burn a token from a given account" + }, + "getAllSplits()": { + "notice": "returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver." + }, + "getCreatorAddress(uint256)": { + "notice": "Extracts the creator address from a given token id" + }, + "getCreatorNonce(uint256)": { + "notice": "Extracts the asset nonce from a given token id" + }, + "getOperatorFilterRegistry()": { + "notice": "returns the operator filter registry." + }, + "getRecipients(uint256)": { + "notice": "returns the royalty recipients for each tokenId." + }, + "getRevealNonce(uint256)": { + "notice": "Extracts the abilities and enhancements hash from a given token id" + }, + "getRoyaltyManager()": { + "notice": "returns the address of royalty manager." + }, + "getTier(uint256)": { + "notice": "Extracts the tier from a given token id" + }, + "getTokenIdByMetadataHash(string)": { + "notice": "returns the tokenId associated with provided metadata hash" + }, + "getTokenRoyaltiesSplitter(uint256)": { + "notice": "returns the address of token royalty splitter." + }, + "getTrustedForwarder()": { + "notice": "return the address of the trusted forwarder" + }, + "initialize(address,address,string,address,address)": { + "notice": "Initialize the contract" + }, + "isBridged(uint256)": { + "notice": "Extracts the bridged flag from a given token id" + }, + "isRevealed(uint256)": { + "notice": "Extracts the revealed flag from a given token id" + }, + "isTrustedForwarder(address)": { + "notice": "return true if the forwarder is the trusted forwarder" + }, + "mint(address,uint256,uint256,string)": { + "notice": "Mint new tokens" + }, + "mintBatch(address,uint256[],uint256[],string[])": { + "notice": "Mint new tokens with catalyst tier chosen by the creator" + }, + "registerAndSubscribe(address,bool)": { + "notice": "This function is used to register Asset contract on the Operator Filterer Registry of OpenSea. Can only be called by admin." + }, + "royaltyInfo(uint256,uint256)": { + "notice": "EIP 2981 royalty info function to return the royalty receiver and royalty amount" + }, + "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)": { + "notice": "Transfers `values` tokens of type `ids` from `from` to `to` (with safety call)." + }, + "safeTransferFrom(address,address,uint256,uint256,bytes)": { + "notice": "Transfers `value` tokens of type `id` from `from` to `to` (with safety call)." + }, + "setApprovalForAll(address,bool)": { + "notice": "Enable or disable approval for `operator` to manage all of the caller's tokens." + }, + "setBaseURI(string)": { + "notice": "Set a new base URI" + }, + "setOperatorRegistry(address)": { + "notice": "sets the operator filter registry address" + }, + "setTokenRoyalties(uint256,address,address)": { + "notice": "could be used to deploy splitter and set tokens royalties" + }, + "setTokenURI(uint256,string)": { + "notice": "Set a new URI for specific tokenid" + }, + "setTrustedForwarder(address)": { + "notice": "Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only" + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements interface `id`." + }, + "uri(uint256)": { + "notice": "returns full token URI, including baseURI and token metadata URI" + } + }, + "notice": "ERC1155 asset token contractMinting and burning tokens is only allowed through separate authorized contracts", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 502, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 505, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 11744, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_trustedForwarder", + "offset": 2, + "slot": "0", + "type": "t_address" + }, + { + "astId": 11855, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 2965, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "50", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 3888, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "100", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 820, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_balances", + "offset": 0, + "slot": "150", + "type": "t_mapping(t_uint256,t_mapping(t_address,t_uint256))" + }, + { + "astId": 826, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_operatorApprovals", + "offset": 0, + "slot": "151", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + }, + { + "astId": 828, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_uri", + "offset": 0, + "slot": "152", + "type": "t_string_storage" + }, + { + "astId": 2035, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "153", + "type": "t_array(t_uint256)47_storage" + }, + { + "astId": 2287, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "200", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 82, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_roles", + "offset": 0, + "slot": "250", + "type": "t_mapping(t_bytes32,t_struct(RoleData)77_storage)" + }, + { + "astId": 377, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "251", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 2313, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_totalSupply", + "offset": 0, + "slot": "300", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 2464, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "301", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 2499, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_baseURI", + "offset": 0, + "slot": "350", + "type": "t_string_storage" + }, + { + "astId": 2503, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_tokenURIs", + "offset": 0, + "slot": "351", + "type": "t_mapping(t_uint256,t_string_storage)" + }, + { + "astId": 2578, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "352", + "type": "t_array(t_uint256)48_storage" + }, + { + "astId": 11876, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "operatorFilterRegistry", + "offset": 0, + "slot": "400", + "type": "t_contract(IOperatorFilterRegistry)12300" + }, + { + "astId": 12080, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "401", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 12327, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "royaltyManager", + "offset": 0, + "slot": "450", + "type": "t_address" + }, + { + "astId": 12331, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_tokenRoyaltiesSplitter", + "offset": 0, + "slot": "451", + "type": "t_mapping(t_uint256,t_address_payable)" + }, + { + "astId": 12334, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "_tokensWithRoyalties", + "offset": 0, + "slot": "452", + "type": "t_array(t_uint256)dyn_storage" + }, + { + "astId": 12726, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "453", + "type": "t_array(t_uint256)47_storage" + }, + { + "astId": 6956, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "hashUsed", + "offset": 0, + "slot": "500", + "type": "t_mapping(t_string_memory_ptr,t_uint256)" + }, + { + "astId": 7653, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "__gap", + "offset": 0, + "slot": "501", + "type": "t_array(t_uint256)49_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_address_payable": { + "encoding": "inplace", + "label": "address payable", + "numberOfBytes": "20" + }, + "t_array(t_uint256)47_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[47]", + "numberOfBytes": "1504" + }, + "t_array(t_uint256)48_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[48]", + "numberOfBytes": "1536" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_array(t_uint256)dyn_storage": { + "base": "t_uint256", + "encoding": "dynamic_array", + "label": "uint256[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IOperatorFilterRegistry)12300": { + "encoding": "inplace", + "label": "contract IOperatorFilterRegistry", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_struct(RoleData)77_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)77_storage" + }, + "t_mapping(t_string_memory_ptr,t_uint256)": { + "encoding": "mapping", + "key": "t_string_memory_ptr", + "label": "mapping(string => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_address_payable)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address payable)", + "numberOfBytes": "32", + "value": "t_address_payable" + }, + "t_mapping(t_uint256,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_uint256,t_string_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => string)", + "numberOfBytes": "32", + "value": "t_string_storage" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_memory_ptr": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(RoleData)77_storage": { + "encoding": "inplace", + "label": "struct AccessControlUpgradeable.RoleData", + "members": [ + { + "astId": 74, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 76, + "contract": "@sandbox-smart-contracts/asset/contracts/Asset.sol:Asset", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/Asset_Proxy.json b/packages/deploy/deployments/mumbai/Asset_Proxy.json new file mode 100644 index 0000000000..4704f68f63 --- /dev/null +++ b/packages/deploy/deployments/mumbai/Asset_Proxy.json @@ -0,0 +1,334 @@ +{ + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "transactionIndex": 11, + "gasUsed": "929195", + "logsBloom": "0x00000004000000000000000000000000400000000800000000000080100000000002000000008400000000000001000000208000002000010000000000440000000080040000000000000000000042800010008000040000040100000000000008000000020000000000020000000801000100800000000080000000000000000080010040000000000000000000000000000000000080040000000000a00000280000000000000000000000000400000000000000000000001040000400004000000020004000000001000000040200000000000400000100108000000060002000080000000000000000200002000004008000080000000000000000100000", + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2", + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "logs": [ + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000d0d6724d44381c21836ceed6d5dac14afae8f168" + ], + "data": "0x", + "logIndex": 43, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 44, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 45, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59", + "0x000000000000000000000000178fd5dec6477364d1beba000e07c18b7be61645", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 46, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x0038c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8", + "0x000000000000000000000000178fd5dec6477364d1beba000e07c18b7be61645", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 47, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de8", + "0x000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da21" + ], + "data": "0x", + "logIndex": 48, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 49, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x178FD5dEC6477364d1BebA000E07C18B7bE61645", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 50, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + }, + { + "transactionIndex": 11, + "blockNumber": 40238283, + "transactionHash": "0x42fdc27e4f1d36a6aed9f20de822d02578da49df4954a4212dd85e1e126db93f", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" + ], + "data": "0x0000000000000000000000000000000000000000000000000004f3a59ada650000000000000000000000000000000000000000000000000fbfc74431548b4534000000000000000000000000000000000000000000001300a4a6dfe298a7f5f700000000000000000000000000000000000000000000000fbfc2508bb9b0e034000000000000000000000000000000000000000000001300a4abd38833825af7", + "logIndex": 51, + "blockHash": "0x89d74debd10b080c48ab4eae8d33dc60066c86bd9a20147eda39b32e7c42d2a2" + } + ], + "blockNumber": 40238283, + "cumulativeGasUsed": "2740330", + "status": 1, + "byzantium": true + }, + "args": [ + "0xD0D6724D44381c21836cEed6d5DaC14aFAe8f168", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xac4a0fb600000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f700000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da210000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/AuthSuperValidator.json b/packages/deploy/deployments/mumbai/AuthSuperValidator.json new file mode 100644 index 0000000000..a200c15f0c --- /dev/null +++ b/packages/deploy/deployments/mumbai/AuthSuperValidator.json @@ -0,0 +1,508 @@ +{ + "address": "0x12467f6e7b23347ABE0109968A9886A6c408d25a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "getSigner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "signer", + "type": "address" + } + ], + "name": "setSigner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "digest", + "type": "bytes32" + } + ], + "name": "verify", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x7cb5db7ab1b56e1cadb6db2fa224f069c8414e38c0ccbfcd8523c00df7aa729a", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x12467f6e7b23347ABE0109968A9886A6c408d25a", + "transactionIndex": 5, + "gasUsed": "888084", + "logsBloom": "0x00000004000000000000000000000000000000000000000000800000000000000002000000008400000000000000000000008000002000000000000000000000000000000000000000000000000000800000000000000000040100000000000000000000020000000000020000000800000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000000000000001040000000004000000000000000000001000400000000000000000000000100108000000020000000000800000000000000000000000000000000000000000000000000100000", + "blockHash": "0x6104c46a7fdb8457164f500f91d3a051800d8091ab78948c2eae98b855114b31", + "transactionHash": "0x7cb5db7ab1b56e1cadb6db2fa224f069c8414e38c0ccbfcd8523c00df7aa729a", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 40238277, + "transactionHash": "0x7cb5db7ab1b56e1cadb6db2fa224f069c8414e38c0ccbfcd8523c00df7aa729a", + "address": "0x12467f6e7b23347ABE0109968A9886A6c408d25a", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 27, + "blockHash": "0x6104c46a7fdb8457164f500f91d3a051800d8091ab78948c2eae98b855114b31" + }, + { + "transactionIndex": 5, + "blockNumber": 40238277, + "transactionHash": "0x7cb5db7ab1b56e1cadb6db2fa224f069c8414e38c0ccbfcd8523c00df7aa729a", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" + ], + "data": "0x0000000000000000000000000000000000000000000000000007bae242e8cbac00000000000000000000000000000000000000000000000fbfe6a3f918e5c3c8000000000000000000000000000000000000000000001300a4190afb2de94c3300000000000000000000000000000000000000000000000fbfdee916d5fcf81c000000000000000000000000000000000000000000001300a420c5dd70d217df", + "logIndex": 28, + "blockHash": "0x6104c46a7fdb8457164f500f91d3a051800d8091ab78948c2eae98b855114b31" + } + ], + "blockNumber": 40238277, + "cumulativeGasUsed": "1487990", + "status": 1, + "byzantium": true + }, + "args": [ + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165" + ], + "numDeployments": 1, + "solcInputHash": "a7dad225e4948fd90c6be2fd4b947044", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"}],\"name\":\"getSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"setSigner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"digest\",\"type\":\"bytes32\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"events\":{\"RoleAdminChanged(bytes32,bytes32,bytes32)\":{\"details\":\"Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._\"},\"RoleGranted(bytes32,address,address)\":{\"details\":\"Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}.\"},\"RoleRevoked(bytes32,address,address)\":{\"details\":\"Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Constructor\",\"params\":{\"admin\":\"Address of the admin that will be able to grant roles\"}},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getSigner(address)\":{\"params\":{\"contractAddress\":\"Address of the contract to get the signer for\"},\"returns\":{\"_0\":\"address of the signer\"}},\"grantRole(bytes32,address)\":{\"details\":\"Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event.\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"renounceRole(bytes32,address)\":{\"details\":\"This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced\",\"params\":{\"account\":\"Account to renounce the role for\",\"role\":\"Role to renounce\"}},\"revokeRole(bytes32,address)\":{\"details\":\"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event.\"},\"setSigner(address,address)\":{\"details\":\"Only the admin can call this function\",\"params\":{\"contractAddress\":\"Address of the contract to set the signer for\",\"signer\":\"Address of the signer\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"verify(bytes,bytes32)\":{\"details\":\"Multipurpose function that can be used to verify signatures with different digests\",\"params\":{\"digest\":\"Digest hash\",\"signature\":\"Signature hash\"},\"returns\":{\"_0\":\"bool\"}}},\"title\":\"AuthSuperValidator\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getSigner(address)\":{\"notice\":\"Gets the signer for a contract\"},\"renounceRole(bytes32,address)\":{\"notice\":\"Prevents the DEFAULT_ADMIN_ROLE from being renounced\"},\"setSigner(address,address)\":{\"notice\":\"Sets the signer for a contract\"},\"verify(bytes,bytes32)\":{\"notice\":\"Takes the signature and the digest and returns if the signer has a backend signer role assigned\"}},\"notice\":\"This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol\":\"AuthSuperValidator\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(account),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0dd6e52cb394d7f5abe5dca2d4908a6be40417914720932de757de34a99ab87f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"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/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\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"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\"},\"@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/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\"},\"@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {AccessControl} from \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\n\\n/// @title AuthSuperValidator\\n/// @author The Sandbox\\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\\ncontract AuthSuperValidator is AccessControl {\\n mapping(address => address) private _signers;\\n\\n /// @dev Constructor\\n /// @param admin Address of the admin that will be able to grant roles\\n constructor(address admin) {\\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\\n }\\n\\n /// @notice Sets the signer for a contract\\n /// @dev Only the admin can call this function\\n /// @param contractAddress Address of the contract to set the signer for\\n /// @param signer Address of the signer\\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\\n _signers[contractAddress] = signer;\\n }\\n\\n /// @notice Gets the signer for a contract\\n /// @param contractAddress Address of the contract to get the signer for\\n /// @return address of the signer\\n function getSigner(address contractAddress) public view returns (address) {\\n return _signers[contractAddress];\\n }\\n\\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\\n /// @dev Multipurpose function that can be used to verify signatures with different digests\\n /// @param signature Signature hash\\n /// @param digest Digest hash\\n /// @return bool\\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\\n address signer = _signers[_msgSender()];\\n require(signer != address(0), \\\"AuthSuperValidator: No signer\\\");\\n address recoveredSigner = ECDSA.recover(digest, signature);\\n return recoveredSigner == signer;\\n }\\n\\n /// @notice Prevents the DEFAULT_ADMIN_ROLE from being renounced\\n /// @dev This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced\\n /// @param role Role to renounce\\n /// @param account Account to renounce the role for\\n function renounceRole(bytes32 role, address account) public override {\\n require(role != DEFAULT_ADMIN_ROLE, \\\"AuthSuperValidator: cant renounce admin role\\\");\\n super.renounceRole(role, account);\\n }\\n}\\n\",\"keccak256\":\"0xd285d5edbc7bedd8dbc3341af44c05ff3bc204ec2e4b6d7bffcd9bb91de3f141\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610fc4380380610fc483398101604081905261002f916100df565b61003a600082610040565b5061010f565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166100db576000828152602081815260408083206001600160a01b03851684529091529020805460ff1916600117905561009a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000602082840312156100f157600080fd5b81516001600160a01b038116811461010857600080fd5b9392505050565b610ea68061011e6000396000f3fe608060405234801561001057600080fd5b50600436106100be5760003560e01c806336568abe1161007657806391d148541161005b57806391d14854146101ae578063a217fddf146101e5578063d547741f146101ed57600080fd5b806336568abe146101885780636b4063411461019b57600080fd5b806317f9fad1116100a757806317f9fad11461012f578063248a9ca3146101445780632f2ff15d1461017557600080fd5b806301ffc9a7146100c35780631180b553146100eb575b600080fd5b6100d66100d1366004610b44565b610200565b60405190151581526020015b60405180910390f35b6101176100f9366004610ba2565b6001600160a01b039081166000908152600160205260409020541690565b6040516001600160a01b0390911681526020016100e2565b61014261013d366004610bbd565b610299565b005b610167610152366004610bf0565b60009081526020819052604090206001015490565b6040519081526020016100e2565b610142610183366004610c09565b6102eb565b610142610196366004610c09565b610315565b6100d66101a9366004610c42565b61039b565b6100d66101bc366004610c09565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b610167600081565b6101426101fb366004610c09565b610426565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061029357507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60006102a48161044b565b506001600160a01b03918216600090815260016020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b6000828152602081905260409020600101546103068161044b565b6103108383610458565b505050565b8161038d5760405162461bcd60e51b815260206004820152602c60248201527f41757468537570657256616c696461746f723a2063616e742072656e6f756e6360448201527f652061646d696e20726f6c65000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61039782826104f6565b5050565b336000908152600160205260408120546001600160a01b0316806104015760405162461bcd60e51b815260206004820152601d60248201527f41757468537570657256616c696461746f723a204e6f207369676e65720000006044820152606401610384565b600061040d848661057e565b6001600160a01b03908116921691909114949350505050565b6000828152602081905260409020600101546104418161044b565b61031083836105a2565b6104558133610621565b50565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610397576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556104b23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b03811633146105745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610384565b61039782826105a2565b600080600061058d8585610694565b9150915061059a816106d9565b509392505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610397576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610397576106528161083e565b61065d836020610850565b60405160200161066e929190610d1b565b60408051601f198184030181529082905262461bcd60e51b825261038491600401610d9c565b60008082516041036106ca5760208301516040840151606085015160001a6106be87828585610a80565b945094505050506106d2565b506000905060025b9250929050565b60008160048111156106ed576106ed610dcf565b036106f55750565b600181600481111561070957610709610dcf565b036107565760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610384565b600281600481111561076a5761076a610dcf565b036107b75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610384565b60038160048111156107cb576107cb610dcf565b036104555760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610384565b60606102936001600160a01b03831660145b6060600061085f836002610dfb565b61086a906002610e12565b67ffffffffffffffff81111561088257610882610c2c565b6040519080825280601f01601f1916602001820160405280156108ac576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106108e3576108e3610e25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061094657610946610e25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000610982846002610dfb565b61098d906001610e12565b90505b6001811115610a2a577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106109ce576109ce610e25565b1a60f81b8282815181106109e4576109e4610e25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93610a2381610e3b565b9050610990565b508315610a795760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610384565b9392505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ab75750600090506003610b3b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610b0b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610b3457600060019250925050610b3b565b9150600090505b94509492505050565b600060208284031215610b5657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a7957600080fd5b80356001600160a01b0381168114610b9d57600080fd5b919050565b600060208284031215610bb457600080fd5b610a7982610b86565b60008060408385031215610bd057600080fd5b610bd983610b86565b9150610be760208401610b86565b90509250929050565b600060208284031215610c0257600080fd5b5035919050565b60008060408385031215610c1c57600080fd5b82359150610be760208401610b86565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610c5557600080fd5b823567ffffffffffffffff80821115610c6d57600080fd5b818501915085601f830112610c8157600080fd5b813581811115610c9357610c93610c2c565b604051601f8201601f19908116603f01168101908382118183101715610cbb57610cbb610c2c565b81604052828152886020848701011115610cd457600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b60005b83811015610d12578181015183820152602001610cfa565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351610d53816017850160208801610cf7565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351610d90816028840160208801610cf7565b01602801949350505050565b6020815260008251806020840152610dbb816040850160208701610cf7565b601f01601f19169190910160400192915050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761029357610293610de5565b8082018082111561029357610293610de5565b634e487b7160e01b600052603260045260246000fd5b600081610e4a57610e4a610de5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220cb3112e33679f37f5c4b7141aff27bc8a23c665dbd654b1ca5b93b7c8ecd2c7864736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100be5760003560e01c806336568abe1161007657806391d148541161005b57806391d14854146101ae578063a217fddf146101e5578063d547741f146101ed57600080fd5b806336568abe146101885780636b4063411461019b57600080fd5b806317f9fad1116100a757806317f9fad11461012f578063248a9ca3146101445780632f2ff15d1461017557600080fd5b806301ffc9a7146100c35780631180b553146100eb575b600080fd5b6100d66100d1366004610b44565b610200565b60405190151581526020015b60405180910390f35b6101176100f9366004610ba2565b6001600160a01b039081166000908152600160205260409020541690565b6040516001600160a01b0390911681526020016100e2565b61014261013d366004610bbd565b610299565b005b610167610152366004610bf0565b60009081526020819052604090206001015490565b6040519081526020016100e2565b610142610183366004610c09565b6102eb565b610142610196366004610c09565b610315565b6100d66101a9366004610c42565b61039b565b6100d66101bc366004610c09565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b610167600081565b6101426101fb366004610c09565b610426565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061029357507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60006102a48161044b565b506001600160a01b03918216600090815260016020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b6000828152602081905260409020600101546103068161044b565b6103108383610458565b505050565b8161038d5760405162461bcd60e51b815260206004820152602c60248201527f41757468537570657256616c696461746f723a2063616e742072656e6f756e6360448201527f652061646d696e20726f6c65000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61039782826104f6565b5050565b336000908152600160205260408120546001600160a01b0316806104015760405162461bcd60e51b815260206004820152601d60248201527f41757468537570657256616c696461746f723a204e6f207369676e65720000006044820152606401610384565b600061040d848661057e565b6001600160a01b03908116921691909114949350505050565b6000828152602081905260409020600101546104418161044b565b61031083836105a2565b6104558133610621565b50565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610397576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556104b23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b03811633146105745760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610384565b61039782826105a2565b600080600061058d8585610694565b9150915061059a816106d9565b509392505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610397576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610397576106528161083e565b61065d836020610850565b60405160200161066e929190610d1b565b60408051601f198184030181529082905262461bcd60e51b825261038491600401610d9c565b60008082516041036106ca5760208301516040840151606085015160001a6106be87828585610a80565b945094505050506106d2565b506000905060025b9250929050565b60008160048111156106ed576106ed610dcf565b036106f55750565b600181600481111561070957610709610dcf565b036107565760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610384565b600281600481111561076a5761076a610dcf565b036107b75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610384565b60038160048111156107cb576107cb610dcf565b036104555760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610384565b60606102936001600160a01b03831660145b6060600061085f836002610dfb565b61086a906002610e12565b67ffffffffffffffff81111561088257610882610c2c565b6040519080825280601f01601f1916602001820160405280156108ac576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106108e3576108e3610e25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061094657610946610e25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000610982846002610dfb565b61098d906001610e12565b90505b6001811115610a2a577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106109ce576109ce610e25565b1a60f81b8282815181106109e4576109e4610e25565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93610a2381610e3b565b9050610990565b508315610a795760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610384565b9392505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610ab75750600090506003610b3b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610b0b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610b3457600060019250925050610b3b565b9150600090505b94509492505050565b600060208284031215610b5657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610a7957600080fd5b80356001600160a01b0381168114610b9d57600080fd5b919050565b600060208284031215610bb457600080fd5b610a7982610b86565b60008060408385031215610bd057600080fd5b610bd983610b86565b9150610be760208401610b86565b90509250929050565b600060208284031215610c0257600080fd5b5035919050565b60008060408385031215610c1c57600080fd5b82359150610be760208401610b86565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215610c5557600080fd5b823567ffffffffffffffff80821115610c6d57600080fd5b818501915085601f830112610c8157600080fd5b813581811115610c9357610c93610c2c565b604051601f8201601f19908116603f01168101908382118183101715610cbb57610cbb610c2c565b81604052828152886020848701011115610cd457600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b60005b83811015610d12578181015183820152602001610cfa565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351610d53816017850160208801610cf7565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351610d90816028840160208801610cf7565b01602801949350505050565b6020815260008251806020840152610dbb816040850160208701610cf7565b601f01601f19169190910160400192915050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761029357610293610de5565b8082018082111561029357610293610de5565b634e487b7160e01b600052603260045260246000fd5b600081610e4a57610e4a610de5565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220cb3112e33679f37f5c4b7141aff27bc8a23c665dbd654b1ca5b93b7c8ecd2c7864736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "events": { + "RoleAdminChanged(bytes32,bytes32,bytes32)": { + "details": "Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._" + }, + "RoleGranted(bytes32,address,address)": { + "details": "Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}." + }, + "RoleRevoked(bytes32,address,address)": { + "details": "Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)" + } + }, + "kind": "dev", + "methods": { + "constructor": { + "details": "Constructor", + "params": { + "admin": "Address of the admin that will be able to grant roles" + } + }, + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getSigner(address)": { + "params": { + "contractAddress": "Address of the contract to get the signer for" + }, + "returns": { + "_0": "address of the signer" + } + }, + "grantRole(bytes32,address)": { + "details": "Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event." + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "renounceRole(bytes32,address)": { + "details": "This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced", + "params": { + "account": "Account to renounce the role for", + "role": "Role to renounce" + } + }, + "revokeRole(bytes32,address)": { + "details": "Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event." + }, + "setSigner(address,address)": { + "details": "Only the admin can call this function", + "params": { + "contractAddress": "Address of the contract to set the signer for", + "signer": "Address of the signer" + } + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + }, + "verify(bytes,bytes32)": { + "details": "Multipurpose function that can be used to verify signatures with different digests", + "params": { + "digest": "Digest hash", + "signature": "Signature hash" + }, + "returns": { + "_0": "bool" + } + } + }, + "title": "AuthSuperValidator", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "getSigner(address)": { + "notice": "Gets the signer for a contract" + }, + "renounceRole(bytes32,address)": { + "notice": "Prevents the DEFAULT_ADMIN_ROLE from being renounced" + }, + "setSigner(address,address)": { + "notice": "Sets the signer for a contract" + }, + "verify(bytes,bytes32)": { + "notice": "Takes the signature and the digest and returns if the signer has a backend signer role assigned" + } + }, + "notice": "This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4897, + "contract": "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol:AuthSuperValidator", + "label": "_roles", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes32,t_struct(RoleData)4892_storage)" + }, + { + "astId": 9680, + "contract": "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol:AuthSuperValidator", + "label": "_signers", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_address)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_bytes32,t_struct(RoleData)4892_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControl.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)4892_storage" + }, + "t_struct(RoleData)4892_storage": { + "encoding": "inplace", + "label": "struct AccessControl.RoleData", + "members": [ + { + "astId": 4889, + "contract": "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol:AuthSuperValidator", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 4891, + "contract": "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol:AuthSuperValidator", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/Catalyst.json b/packages/deploy/deployments/mumbai/Catalyst.json new file mode 100644 index 0000000000..aa6899bd93 --- /dev/null +++ b/packages/deploy/deployments/mumbai/Catalyst.json @@ -0,0 +1,1538 @@ +{ + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "baseURI", + "type": "string" + } + ], + "name": "BaseURISet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newDefaultRoyaltyRecipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDefaultRoyaltyAmount", + "type": "uint256" + } + ], + "name": "DefaultRoyaltyChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "catalystId", + "type": "uint256" + } + ], + "name": "NewCatalystTypeAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "OperatorFilterRegistrySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "OperatorRegistrySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_royaltyManager", + "type": "address" + } + ], + "name": "RoyaltyManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "ipfsCID", + "type": "string" + } + ], + "name": "addNewCatalystType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "burnBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "burnBatchFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOperatorFilterRegistry", + "outputs": [ + { + "internalType": "contract IOperatorFilterRegistry", + "name": "operatorFilterRegistryAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRoyaltyManager", + "outputs": [ + { + "internalType": "contract IRoyaltyManager", + "name": "royaltyManagerAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "highestTierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_baseUri", + "type": "string" + }, + { + "internalType": "address", + "name": "_trustedForwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_subscription", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultMinter", + "type": "address" + }, + { + "internalType": "string[]", + "name": "_catalystIpfsCID", + "type": "string[]" + }, + { + "internalType": "address", + "name": "_royaltyManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "mintBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subscriptionOrRegistrantToCopy", + "type": "address" + }, + { + "internalType": "bool", + "name": "subscribe", + "type": "bool" + } + ], + "name": "registerAndSubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salePrice", + "type": "uint256" + } + ], + "name": "royaltyInfo", + "outputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "royaltyAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "baseURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + } + ], + "name": "setMetadataHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "setOperatorRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x059C6c226ec83742932B259153f63e333B767A50", + "transactionIndex": 7, + "gasUsed": "1562454", + "logsBloom": "0x04000004000000000000008000000000400000000800000000000090100000000002000000008420000000000001004000208100020400000000000000040000000090040004010000000020000002800010000000040000000100000000000008000004020000000000020000000801000000800000000080000000001000000000010440000210000020000000001000000800100081042000000000a00000200000000000000000000100000400000000000000800000003000080400404000000020004000000001000000040200001000008400000100108000001060002000090000000000000000200000000804000000088000001002000000100000", + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58", + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000000675d3ad952e443635ad76a22dceab391556a0d3" + ], + "data": "0x", + "logIndex": 37, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 38, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59", + "0x000000000000000000000000059c6c226ec83742932b259153f63e333b767a50", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 39, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x0038c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8", + "0x000000000000000000000000059c6c226ec83742932b259153f63e333b767a50", + "0x0000000000000000000000004bd0ad9d60d686a259fbcd8c56ce6100d7031e35", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 40, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0xf9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000", + "logIndex": 41, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 42, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 43, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de8", + "0x000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da21" + ], + "data": "0x", + "logIndex": 44, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261667962656965636e7a37736e7837363374637877627369746275636c74637870376d6135736971626764613335626c3374736665657469346d000000000000000000000000000000000000000000000000000000000000", + "logIndex": 45, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696235746b793364677363377a793633376466756e62347a77776e707a6f33773369357465706266656534326571337372776e7771000000000000000000000000000000000000000000000000000000000000", + "logIndex": 46, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000002" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696567657676696d357133617469346874736e63787773656a6663336c626b7a6237776e326132667a7468633674736f663776376d000000000000000000000000000000000000000000000000000000000000", + "logIndex": 47, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000003" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696668746b6f75356133327872746b746476667172766768346d70326f68766c79716473696835786b346b67636679777478656669000000000000000000000000000000000000000000000000000000000000", + "logIndex": 48, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000004" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696771706237716f3369716b61343234336f6168336e6b6136616778336e6d76777a6175787a65326a7a6e6f7478337a776f7a7165000000000000000000000000000000000000000000000000000000000000", + "logIndex": 49, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000005" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569683369747369776b6e3275727a66766732366d627933737367667368766472367a6661627236727878726c7a68656471696c3465000000000000000000000000000000000000000000000000000000000000", + "logIndex": 50, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000006" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569626d6e6761756f7a7a69647a3265657679796233756d66326577377a6578696e673367687570366c37696f32616f3532326d7679000000000000000000000000000000000000000000000000000000000000", + "logIndex": 51, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 52, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 53, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000f903ba9e006193c1527bfbe65fe2123704ea3f99" + ], + "data": "0x00000000000000000000000000000000000000000000000000085390c178ca0000000000000000000000000000000000000000000000000fbfeef789dc0bb1d4000000000000000000000000000000000000000000001142a6bda6715ef2d99f00000000000000000000000000000000000000000000000fbfe6a3f91a92e7d4000000000000000000000000000000000000000000001142a6c5fa02206ba39f", + "logIndex": 54, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + } + ], + "blockNumber": 40238265, + "cumulativeGasUsed": "2378638", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0675d3Ad952e443635AD76A22Dceab391556A0d3", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xf3bdecc100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f70000000000000000000000004bd0ad9d60d686a259fbcd8c56ce6100d7031e3500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc6121811650000000000000000000000000000000000000000000000000000000000000120000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da210000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000003b6261667962656965636e7a37736e7837363374637877627369746275636c74637870376d6135736971626764613335626c3374736665657469346d0000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696235746b793364677363377a793633376466756e62347a77776e707a6f33773369357465706266656534326571337372776e77710000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696567657676696d357133617469346874736e63787773656a6663336c626b7a6237776e326132667a7468633674736f663776376d0000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696668746b6f75356133327872746b746476667172766768346d70326f68766c79716473696835786b346b676366797774786566690000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696771706237716f3369716b61343234336f6168336e6b6136616778336e6d76777a6175787a65326a7a6e6f7478337a776f7a71650000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569683369747369776b6e3275727a66766732366d627933737367667368766472367a6661627236727878726c7a68656471696c34650000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569626d6e6761756f7a7a69647a3265657679796233756d66326577377a6578696e673367687570366c37696f32616f3532326d76790000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "ipfs://", + "0x69015912aa33720b842dcd6ac059ed623f28d9f7", + "0x4bd0ad9D60d686a259fBCD8C56CE6100D7031e35", + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165", + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165", + [ + "bafybeiecnz7snx763tcxwbsitbucltcxp7ma5siqbgda35bl3tsfeeti4m", + "bafkreib5tky3dgsc7zy637dfunb4zwwnpzo3w3i5tepbfee42eq3srwnwq", + "bafkreiegevvim5q3ati4htsncxwsejfc3lbkzb7wn2a2fzthc6tsof7v7m", + "bafkreifhtkou5a32xrtktdvfqrvgh4mp2ohvlyqdsih5xk4kgcfywtxefi", + "bafkreigqpb7qo3iqka4243oah3nka6agx3nmvwzauxze2jznotx3zwozqe", + "bafkreih3itsiwkn2urzfvg26mby3ssgfshvdr6zfabr6rxxrlzhedqil4e", + "bafkreibmngauozzidz2eevyyb3umf2ew7zexing3ghup6l7io2ao522mvy" + ], + "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21" + ] + }, + "implementation": "0x0675d3Ad952e443635AD76A22Dceab391556A0d3", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/Catalyst_Implementation.json b/packages/deploy/deployments/mumbai/Catalyst_Implementation.json new file mode 100644 index 0000000000..3b0c166831 --- /dev/null +++ b/packages/deploy/deployments/mumbai/Catalyst_Implementation.json @@ -0,0 +1,1756 @@ +{ + "address": "0x0675d3Ad952e443635AD76A22Dceab391556A0d3", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "baseURI", + "type": "string" + } + ], + "name": "BaseURISet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newDefaultRoyaltyRecipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDefaultRoyaltyAmount", + "type": "uint256" + } + ], + "name": "DefaultRoyaltyChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "catalystId", + "type": "uint256" + } + ], + "name": "NewCatalystTypeAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "OperatorFilterRegistrySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "OperatorRegistrySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_royaltyManager", + "type": "address" + } + ], + "name": "RoyaltyManagerSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "TransferBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "TransferSingle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarderAddress", + "type": "address" + } + ], + "name": "TrustedForwarderChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newTrustedForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "value", + "type": "string" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "URI", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "ipfsCID", + "type": "string" + } + ], + "name": "addNewCatalystType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "accounts", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + } + ], + "name": "balanceOfBatch", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + } + ], + "name": "burnBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "burnBatchFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "exists", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getOperatorFilterRegistry", + "outputs": [ + { + "internalType": "contract IOperatorFilterRegistry", + "name": "operatorFilterRegistryAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRoyaltyManager", + "outputs": [ + { + "internalType": "contract IRoyaltyManager", + "name": "royaltyManagerAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "highestTierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_baseUri", + "type": "string" + }, + { + "internalType": "address", + "name": "_trustedForwarder", + "type": "address" + }, + { + "internalType": "address", + "name": "_subscription", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "_defaultMinter", + "type": "address" + }, + { + "internalType": "string[]", + "name": "_catalystIpfsCID", + "type": "string[]" + }, + { + "internalType": "address", + "name": "_royaltyManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "mintBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "subscriptionOrRegistrantToCopy", + "type": "address" + }, + { + "internalType": "bool", + "name": "subscribe", + "type": "bool" + } + ], + "name": "registerAndSubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_salePrice", + "type": "uint256" + } + ], + "name": "royaltyInfo", + "outputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "royaltyAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "ids", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "values", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeBatchTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "baseURI", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "metadataHash", + "type": "string" + } + ], + "name": "setMetadataHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "registry", + "type": "address" + } + ], + "name": "setOperatorRegistry", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "uri", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x351a3016385979c4d0a1f0076e2aa76667f7ea8c304c8a405abde8a8aa5d6796", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x0675d3Ad952e443635AD76A22Dceab391556A0d3", + "transactionIndex": 8, + "gasUsed": "4007590", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000010000000000002000000000020000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000010000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000200000200000000000000000004000000400000000800000000000000000000000004000000000000000000001000000040000000000000000000000108000001000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x9cdb38d7acfaffedf487e3dc1ad5877b90b1642a65160aeab2f44adf8564c06a", + "transactionHash": "0x351a3016385979c4d0a1f0076e2aa76667f7ea8c304c8a405abde8a8aa5d6796", + "logs": [ + { + "transactionIndex": 8, + "blockNumber": 40238262, + "transactionHash": "0x351a3016385979c4d0a1f0076e2aa76667f7ea8c304c8a405abde8a8aa5d6796", + "address": "0x0675d3Ad952e443635AD76A22Dceab391556A0d3", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 27, + "blockHash": "0x9cdb38d7acfaffedf487e3dc1ad5877b90b1642a65160aeab2f44adf8564c06a" + }, + { + "transactionIndex": 8, + "blockNumber": 40238262, + "transactionHash": "0x351a3016385979c4d0a1f0076e2aa76667f7ea8c304c8a405abde8a8aa5d6796", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000f903ba9e006193c1527bfbe65fe2123704ea3f99" + ], + "data": "0x0000000000000000000000000000000000000000000000000022e1f5e46ea4ae00000000000000000000000000000000000000000000000fc011d97fc4c70e2e000000000000000000000000000000000000000000001142a61953d4843c35e600000000000000000000000000000000000000000000000fbfeef789e0586980000000000000000000000000000000000000000000001142a63c35ca68aada94", + "logIndex": 28, + "blockHash": "0x9cdb38d7acfaffedf487e3dc1ad5877b90b1642a65160aeab2f44adf8564c06a" + } + ], + "blockNumber": 40238262, + "cumulativeGasUsed": "4981109", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "a7dad225e4948fd90c6be2fd4b947044", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"}],\"name\":\"BaseURISet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newDefaultRoyaltyRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newDefaultRoyaltyAmount\",\"type\":\"uint256\"}],\"name\":\"DefaultRoyaltyChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"catalystId\",\"type\":\"uint256\"}],\"name\":\"NewCatalystTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"OperatorFilterRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"OperatorRegistrySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_royaltyManager\",\"type\":\"address\"}],\"name\":\"RoyaltyManagerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarderAddress\",\"type\":\"address\"}],\"name\":\"TrustedForwarderChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newTrustedForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"TrustedForwarderSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BURNER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MINTER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"ipfsCID\",\"type\":\"string\"}],\"name\":\"addNewCatalystType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"accounts\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"}],\"name\":\"burnBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"burnBatchFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"exists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOperatorFilterRegistry\",\"outputs\":[{\"internalType\":\"contract IOperatorFilterRegistry\",\"name\":\"operatorFilterRegistryAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRoyaltyManager\",\"outputs\":[{\"internalType\":\"contract IRoyaltyManager\",\"name\":\"royaltyManagerAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTrustedForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"highestTierIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_baseUri\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_trustedForwarder\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_subscription\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_defaultMinter\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_catalystIpfsCID\",\"type\":\"string[]\"},{\"internalType\":\"address\",\"name\":\"_royaltyManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isTrustedForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"mintBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"subscriptionOrRegistrantToCopy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"subscribe\",\"type\":\"bool\"}],\"name\":\"registerAndSubscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_salePrice\",\"type\":\"uint256\"}],\"name\":\"royaltyInfo\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"royaltyAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"baseURI\",\"type\":\"string\"}],\"name\":\"setBaseURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"metadataHash\",\"type\":\"string\"}],\"name\":\"setMetadataHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"registry\",\"type\":\"address\"}],\"name\":\"setOperatorRegistry\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"trustedForwarder\",\"type\":\"address\"}],\"name\":\"setTrustedForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"uri\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"details\":\"An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to provide a variety of features including, AccessControl, URIStorage, Burnable and more. The contract includes support for meta transactions.\",\"events\":{\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`.\"},\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"RoleAdminChanged(bytes32,bytes32,bytes32)\":{\"details\":\"Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._\"},\"RoleGranted(bytes32,address,address)\":{\"details\":\"Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}.\"},\"RoleRevoked(bytes32,address,address)\":{\"details\":\"Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)\"},\"TransferBatch(address,address,address,uint256[],uint256[])\":{\"details\":\"Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all transfers.\"},\"TransferSingle(address,address,address,uint256,uint256)\":{\"details\":\"Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\"},\"TrustedForwarderSet(address,address,address)\":{\"params\":{\"newTrustedForwarder\":\"new trusted forwarder\",\"oldTrustedForwarder\":\"old trusted forwarder\",\"operator\":\"the sender of the transaction\"}},\"URI(string,uint256)\":{\"details\":\"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}.\"}},\"kind\":\"dev\",\"methods\":{\"addNewCatalystType(string)\":{\"params\":{\"ipfsCID\":\"The IPFS content identifiers for the catalyst\"}},\"balanceOf(address,uint256)\":{\"details\":\"See {IERC1155-balanceOf}. Requirements: - `account` cannot be the zero address.\"},\"balanceOfBatch(address[],uint256[])\":{\"details\":\"See {IERC1155-balanceOfBatch}. Requirements: - `accounts` and `ids` must have the same length.\"},\"burnBatchFrom(address,uint256[],uint256[])\":{\"params\":{\"account\":\"The address to burn from\",\"amounts\":\"The amounts to be burned\",\"ids\":\"The token ids to burn\"}},\"burnFrom(address,uint256,uint256)\":{\"params\":{\"account\":\"The address to burn from\",\"amount\":\"The amount to be burned\",\"id\":\"The token id to burn\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"exists(uint256)\":{\"details\":\"Indicates whether any token exist with a given id, or not.\"},\"getOperatorFilterRegistry()\":{\"returns\":{\"operatorFilterRegistryAddress\":\"address of operator filter registry contract.\"}},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoyaltyManager()\":{\"returns\":{\"royaltyManagerAddress\":\"address of royalty manager contract.\"}},\"getTrustedForwarder()\":{\"returns\":{\"_0\":\"return the address of the trusted forwarder\"}},\"grantRole(bytes32,address)\":{\"details\":\"Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event.\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"initialize(string,address,address,address,address,string[],address)\":{\"params\":{\"_baseUri\":\"The base URI for the token metadata, most likely set to ipfs://.\",\"_catalystIpfsCID\":\"The IPFS content identifiers for each catalyst.\",\"_defaultAdmin\":\"The default admin address.\",\"_defaultMinter\":\"The default minter address.\",\"_royaltyManager\":\", the address of the Manager contract for common royalty recipient\",\"_subscription\":\"The subscription address.\",\"_trustedForwarder\":\"The trusted forwarder for meta transactions.\"}},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC1155-isApprovedForAll}.\"},\"isTrustedForwarder(address)\":{\"params\":{\"forwarder\":\"trusted forwarder address to check\"},\"returns\":{\"_0\":\"true if the address is the same as the trusted forwarder\"}},\"mint(address,uint256,uint256)\":{\"params\":{\"amount\":\"The amount to be minted\",\"id\":\"The token id to mint\",\"to\":\"The address that will own the minted token\"}},\"mintBatch(address,uint256[],uint256[])\":{\"params\":{\"amounts\":\"The amounts to be minted per token id\",\"ids\":\"The token ids to mint\",\"to\":\"The address that will own the minted tokens\"}},\"registerAndSubscribe(address,bool)\":{\"details\":\"used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\",\"params\":{\"subscribe\":\"bool to signify subscription \\\"true\\\"\\\" or to copy the list \\\"false\\\".\",\"subscriptionOrRegistrantToCopy\":\"registration address of the list to subscribe.\"}},\"renounceRole(bytes32,address)\":{\"details\":\"Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event.\"},\"revokeRole(bytes32,address)\":{\"details\":\"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event.\"},\"royaltyInfo(uint256,uint256)\":{\"details\":\"tokenId is one of the EIP2981 args for this function can't be removed\",\"params\":{\"_salePrice\":\"the price of token on which the royalty is calculated\"},\"returns\":{\"receiver\":\"the receiver of royalty\",\"royaltyAmount\":\"the amount of royalty\"}},\"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\":{\"details\":\"call data should be optimized to order ids so packedBalance can be used efficiently.\",\"params\":{\"data\":\"additional data accompanying the transfer.\",\"from\":\"address from which tokens are transfered.\",\"ids\":\"ids of each token type transfered.\",\"to\":\"address to which the token will be transfered.\",\"values\":\"amount of each token type transfered.\"}},\"safeTransferFrom(address,address,uint256,uint256,bytes)\":{\"params\":{\"data\":\"additional data accompanying the transfer.\",\"from\":\"address from which tokens are transfered.\",\"id\":\"the token type transfered.\",\"to\":\"address to which the token will be transfered.\",\"value\":\"amount of token transfered.\"}},\"setApprovalForAll(address,bool)\":{\"params\":{\"approved\":\"whether to approve or revoke\",\"operator\":\"address which will be granted rights to transfer all tokens of the caller.\"}},\"setBaseURI(string)\":{\"params\":{\"baseURI\":\"The new base URI\"}},\"setMetadataHash(uint256,string)\":{\"params\":{\"metadataHash\":\"The new URI\",\"tokenId\":\"The token id to set URI for\"}},\"setOperatorRegistry(address)\":{\"params\":{\"registry\":\"the address of the registry\"}},\"setTrustedForwarder(address)\":{\"details\":\"Change the address of the trusted forwarder for meta-TX\",\"params\":{\"trustedForwarder\":\"The new trustedForwarder\"}},\"supportsInterface(bytes4)\":{\"params\":{\"interfaceId\":\"the interface identifier, as specified in ERC-165.\"},\"returns\":{\"_0\":\"`true` if the contract implements `interfaceId`.\"}},\"totalSupply(uint256)\":{\"details\":\"Total amount of tokens in with a given id.\"},\"uri(uint256)\":{\"params\":{\"tokenId\":\"The token id to get URI for\"},\"returns\":{\"_0\":\"tokenURI the URI of the token\"}}},\"title\":\"Catalyst\",\"version\":1},\"userdoc\":{\"events\":{\"TrustedForwarderSet(address,address,address)\":{\"notice\":\"Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\"}},\"kind\":\"user\",\"methods\":{\"addNewCatalystType(string)\":{\"notice\":\"Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\"},\"burnBatchFrom(address,uint256[],uint256[])\":{\"notice\":\"Burns a batch of tokens from a specific address\"},\"burnFrom(address,uint256,uint256)\":{\"notice\":\"Burns a specified amount of tokens from a specific address\"},\"getOperatorFilterRegistry()\":{\"notice\":\"returns the operator filter registry.\"},\"getRoyaltyManager()\":{\"notice\":\"returns the royalty manager\"},\"getTrustedForwarder()\":{\"notice\":\"return the address of the trusted forwarder\"},\"initialize(string,address,address,address,address,string[],address)\":{\"notice\":\"Initialize the contract, setting up initial values for various features.\"},\"isTrustedForwarder(address)\":{\"notice\":\"return true if the forwarder is the trusted forwarder\"},\"mint(address,uint256,uint256)\":{\"notice\":\"Mints a new token, limited to MINTER_ROLE only\"},\"mintBatch(address,uint256[],uint256[])\":{\"notice\":\"Mints a batch of tokens, limited to MINTER_ROLE only\"},\"registerAndSubscribe(address,bool)\":{\"notice\":\"This function is used to register Catalyst contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.\"},\"royaltyInfo(uint256,uint256)\":{\"notice\":\"Returns how much royalty is owed and to whom based on ERC2981\"},\"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\":{\"notice\":\"Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\"},\"safeTransferFrom(address,address,uint256,uint256,bytes)\":{\"notice\":\"Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\"},\"setApprovalForAll(address,bool)\":{\"notice\":\"Enable or disable approval for `operator` to manage all of the caller's tokens.\"},\"setBaseURI(string)\":{\"notice\":\"Set a new base URI\"},\"setMetadataHash(uint256,string)\":{\"notice\":\"Set a new URI for specific tokenid\"},\"setOperatorRegistry(address)\":{\"notice\":\"sets filter registry address\"},\"setTrustedForwarder(address)\":{\"notice\":\"Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\"},\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements interface `id`.\"},\"uri(uint256)\":{\"notice\":\"returns full token URI, including baseURI and token metadata URI\"}},\"notice\":\"This contract manages catalysts which are used to mint new assets.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/asset/contracts/Catalyst.sol\":\"Catalyst\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/// @author: manifold.xyz\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\nstruct Recipient {\\n address payable recipient;\\n uint16 bps;\\n}\\n\\ninterface IRoyaltySplitter is IERC165 {\\n /**\\n * @dev Set the splitter recipients. Total bps must total 10000.\\n */\\n function setRecipients(Recipient[] calldata recipients) external;\\n\\n /**\\n * @dev Get the splitter recipients;\\n */\\n function getRecipients() external view returns (Recipient[] memory);\\n}\\n\",\"keccak256\":\"0xc507963f66c4238d25e69d2d05ac5995c549aa89789e89e7a556403221547c6d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlUpgradeable.sol\\\";\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\\n function __AccessControl_init() internal onlyInitializing {\\n }\\n\\n function __AccessControl_init_unchained() internal onlyInitializing {\\n }\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n StringsUpgradeable.toHexString(account),\\n \\\" is missing role \\\",\\n StringsUpgradeable.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xfeefb24d068524440e1ba885efdf105d91f83504af3c2d745ffacc4595396831\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControlUpgradeable {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xb8f5302f12138c5561362e88a78d061573e6298b7a1a5afe84a1e2c8d4d5aeaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the NFT Royalty Standard.\\n *\\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\\n *\\n * _Available since v4.5._\\n */\\ninterface IERC2981Upgradeable is IERC165Upgradeable {\\n /**\\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\\n */\\n function royaltyInfo(\\n uint256 tokenId,\\n uint256 salePrice\\n ) external view returns (address receiver, uint256 royaltyAmount);\\n}\\n\",\"keccak256\":\"0x1a94069aa241fa1ebb4409d02a405c932d3ad7e875bdd5587c88244da210ccdf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \\\"./IERC1155Upgradeable.sol\\\";\\nimport \\\"./IERC1155ReceiverUpgradeable.sol\\\";\\nimport \\\"./extensions/IERC1155MetadataURIUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\\n __ERC1155_init_unchained(uri_);\\n }\\n\\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\\n _setURI(uri_);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\\n return\\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\\n bytes4 response\\n ) {\\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[47] private __gap;\\n}\\n\",\"keccak256\":\"0xc3e465e1fdd0e491688ad75ef1b946e1680e7f9f78bf5beeefd6daed8693c856\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\\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\":\"0xffcb29612efb57efc8f0d4897deb5abaeac830022c59a3aa17446d698dbc856b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\\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\",\"keccak256\":\"0xf51f292659a77777c0ed7375a39683d8bee53b86a6e7bd0c76f34ce7aa37a3a8\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1155Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\\n * own tokens and those that they have been approved to use.\\n *\\n * _Available since v3.1._\\n */\\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\\n function __ERC1155Burnable_init() internal onlyInitializing {\\n }\\n\\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\\n }\\n function burn(address account, uint256 id, uint256 value) public virtual {\\n require(\\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\\n \\\"ERC1155: caller is not token owner or approved\\\"\\n );\\n\\n _burn(account, id, value);\\n }\\n\\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\\n require(\\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\\n \\\"ERC1155: caller is not token owner or approved\\\"\\n );\\n\\n _burnBatch(account, ids, values);\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x048a492eee88c80ecc0354486e8e0ab99490b44a6fb28833b3cfb45d573f18d7\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1155Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\\n *\\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\\n * clearly identified. Note: While a totalSupply of 1 might mean the\\n * corresponding is an NFT, there is no guarantees that no other token with the\\n * same id are not going to be minted.\\n */\\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\\n function __ERC1155Supply_init() internal onlyInitializing {\\n }\\n\\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\\n }\\n mapping(uint256 => uint256) private _totalSupply;\\n\\n /**\\n * @dev Total amount of tokens in with a given id.\\n */\\n function totalSupply(uint256 id) public view virtual returns (uint256) {\\n return _totalSupply[id];\\n }\\n\\n /**\\n * @dev Indicates whether any token exist with a given id, or not.\\n */\\n function exists(uint256 id) public view virtual returns (bool) {\\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\\n }\\n\\n /**\\n * @dev See {ERC1155-_beforeTokenTransfer}.\\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 override {\\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\\n\\n if (from == address(0)) {\\n for (uint256 i = 0; i < ids.length; ++i) {\\n _totalSupply[ids[i]] += amounts[i];\\n }\\n }\\n\\n if (to == address(0)) {\\n for (uint256 i = 0; i < ids.length; ++i) {\\n uint256 id = ids[i];\\n uint256 amount = amounts[i];\\n uint256 supply = _totalSupply[id];\\n require(supply >= amount, \\\"ERC1155: burn amount exceeds totalSupply\\\");\\n unchecked {\\n _totalSupply[id] = supply - amount;\\n }\\n }\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf7bdbcbb9fcf42997f280db8c02070e9c561406e6971ff680c6c43f92065ac9e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../ERC1155Upgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev ERC1155 token with storage based token URI management.\\n * Inspired by the ERC721URIStorage extension\\n *\\n * _Available since v4.6._\\n */\\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\\n function __ERC1155URIStorage_init() internal onlyInitializing {\\n __ERC1155URIStorage_init_unchained();\\n }\\n\\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\\n _baseURI = \\\"\\\";\\n }\\n using StringsUpgradeable for uint256;\\n\\n // Optional base URI\\n string private _baseURI;\\n\\n // Optional mapping for token URIs\\n mapping(uint256 => string) private _tokenURIs;\\n\\n /**\\n * @dev See {IERC1155MetadataURI-uri}.\\n *\\n * This implementation returns the concatenation of the `_baseURI`\\n * and the token-specific uri if the latter is set\\n *\\n * This enables the following behaviors:\\n *\\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\\n * is empty per default);\\n *\\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\\n * which in most cases will contain `ERC1155._uri`;\\n *\\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\\n * uri value set, then the result is empty.\\n */\\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\\n string memory tokenURI = _tokenURIs[tokenId];\\n\\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\\n }\\n\\n /**\\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\\n */\\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\\n _tokenURIs[tokenId] = tokenURI;\\n emit URI(uri(tokenId), tokenId);\\n }\\n\\n /**\\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\\n */\\n function _setBaseURI(string memory baseURI) internal virtual {\\n _baseURI = baseURI;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[48] private __gap;\\n}\\n\",\"keccak256\":\"0x9a1218747a17239e2fcab2efc14099379387f114c7ad22c69a23b7d67ec0eaa2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \\\"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\\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\",\"keccak256\":\"0xa350df12a8c10e821af05e0863f44e8317a0efa44df27bfd5dc1d63fdfa3c448\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\\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\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\\\";\\nimport \\\"./math/SignedMathUpgradeable.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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\":\"0xb96dc79b65b7c37937919dcdb356a969ce0aa2e8338322bf4dc027a3c9c9a7eb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\\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\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\\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\":\"0x2bc0007987c229ae7624eb29be6a9b84f6a6a5872f76248b15208b131ea41c4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\\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\":\"0x88f6b7bba3ee33eeb741f9a0f5bc98b6e6e352d0fe4905377bb328590f84095a\",\"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\"},\"@sandbox-smart-contracts/asset/contracts/Catalyst.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\nimport {ERC1155Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\\\";\\nimport {\\n AccessControlUpgradeable,\\n ContextUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\\\";\\nimport {\\n ERC1155BurnableUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\\\";\\nimport {\\n ERC1155SupplyUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\\\";\\nimport {\\n ERC1155URIStorageUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\\\";\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {\\n OperatorFiltererUpgradeable,\\n IOperatorFilterRegistry\\n} from \\\"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\\\";\\nimport {\\n RoyaltyDistributor\\n} from \\\"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\\\";\\nimport {\\n ERC2771HandlerUpgradeable\\n} from \\\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\\\";\\nimport {ICatalyst} from \\\"./interfaces/ICatalyst.sol\\\";\\n\\n/// @title Catalyst\\n/// @author The Sandbox\\n/// @notice This contract manages catalysts which are used to mint new assets.\\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\\n/// The contract includes support for meta transactions.\\ncontract Catalyst is\\n ICatalyst,\\n Initializable,\\n ERC1155Upgradeable,\\n ERC1155BurnableUpgradeable,\\n ERC1155SupplyUpgradeable,\\n ERC1155URIStorageUpgradeable,\\n ERC2771HandlerUpgradeable,\\n AccessControlUpgradeable,\\n OperatorFiltererUpgradeable,\\n RoyaltyDistributor\\n{\\n bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER_ROLE\\\");\\n bytes32 public constant BURNER_ROLE = keccak256(\\\"BURNER_ROLE\\\");\\n\\n uint256 public highestTierIndex;\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n modifier onlyValidId(uint256 tokenId) {\\n require(tokenId > 0 && tokenId <= highestTierIndex, \\\"Catalyst: invalid catalyst id\\\");\\n _;\\n }\\n\\n /// @notice Initialize the contract, setting up initial values for various features.\\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\\n /// @param _subscription The subscription address.\\n /// @param _defaultAdmin The default admin address.\\n /// @param _defaultMinter The default minter address.\\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\\n function initialize(\\n string memory _baseUri,\\n address _trustedForwarder,\\n address _subscription,\\n address _defaultAdmin,\\n address _defaultMinter,\\n string[] memory _catalystIpfsCID,\\n address _royaltyManager\\n ) external initializer {\\n require(bytes(_baseUri).length != 0, \\\"Catalyst: URI empty\\\");\\n require(_trustedForwarder != address(0), \\\"Catalyst: 1-Zero address\\\");\\n require(_subscription != address(0), \\\"Catalyst: 2-Zero address\\\");\\n require(_defaultAdmin != address(0), \\\"Catalyst: 3-Zero address\\\");\\n require(_defaultMinter != address(0), \\\"Catalyst: 4-Zero address\\\");\\n require(_royaltyManager != address(0), \\\"Catalyst: 5-Zero address\\\");\\n __ERC1155_init(_baseUri);\\n __AccessControl_init();\\n __ERC1155Burnable_init();\\n __ERC1155Supply_init();\\n __ERC1155URIStorage_init();\\n __ERC2771Handler_init(_trustedForwarder);\\n __OperatorFilterer_init(_subscription, true);\\n _setBaseURI(_baseUri);\\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\\n _grantRole(MINTER_ROLE, _defaultMinter);\\n __RoyaltyDistributor_init(_royaltyManager);\\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\\n require(bytes(_catalystIpfsCID[i]).length != 0, \\\"Catalyst: CID cant be empty\\\");\\n _setURI(i, _catalystIpfsCID[i]);\\n highestTierIndex = i;\\n }\\n }\\n\\n /// @notice Mints a new token, limited to MINTER_ROLE only\\n /// @param to The address that will own the minted token\\n /// @param id The token id to mint\\n /// @param amount The amount to be minted\\n function mint(\\n address to,\\n uint256 id,\\n uint256 amount\\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\\n _mint(to, id, amount, \\\"\\\");\\n }\\n\\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\\n /// @param to The address that will own the minted tokens\\n /// @param ids The token ids to mint\\n /// @param amounts The amounts to be minted per token id\\n function mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external onlyRole(MINTER_ROLE) {\\n for (uint256 i = 0; i < ids.length; i++) {\\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \\\"Catalyst: invalid catalyst id\\\");\\n }\\n _mintBatch(to, ids, amounts, \\\"\\\");\\n }\\n\\n /// @notice Burns a specified amount of tokens from a specific address\\n /// @param account The address to burn from\\n /// @param id The token id to burn\\n /// @param amount The amount to be burned\\n function burnFrom(\\n address account,\\n uint256 id,\\n uint256 amount\\n ) external onlyRole(BURNER_ROLE) {\\n _burn(account, id, amount);\\n }\\n\\n /// @notice Burns a batch of tokens from a specific address\\n /// @param account The address to burn from\\n /// @param ids The token ids to burn\\n /// @param amounts The amounts to be burned\\n function burnBatchFrom(\\n address account,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external onlyRole(BURNER_ROLE) {\\n _burnBatch(account, ids, amounts);\\n }\\n\\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\\n /// @param ipfsCID The IPFS content identifiers for the catalyst\\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(bytes(ipfsCID).length != 0, \\\"Catalyst: CID cant be empty\\\");\\n uint256 newCatId = ++highestTierIndex;\\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\\n emit NewCatalystTypeAdded(newCatId);\\n }\\n\\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\\n /// @dev Change the address of the trusted forwarder for meta-TX\\n /// @param trustedForwarder The new trustedForwarder\\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(trustedForwarder != address(0), \\\"Catalyst: Zero address\\\");\\n _setTrustedForwarder(trustedForwarder);\\n }\\n\\n /// @notice Set a new URI for specific tokenid\\n /// @param tokenId The token id to set URI for\\n /// @param metadataHash The new URI\\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\\n external\\n onlyRole(DEFAULT_ADMIN_ROLE)\\n onlyValidId(tokenId)\\n {\\n require(bytes(metadataHash).length != 0, \\\"Catalyst: Metadata hash empty\\\");\\n _setURI(tokenId, metadataHash);\\n }\\n\\n /// @notice Set a new base URI\\n /// @param baseURI The new base URI\\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(bytes(baseURI).length != 0, \\\"Catalyst: URI empty\\\");\\n _setBaseURI(baseURI);\\n emit BaseURISet(baseURI);\\n }\\n\\n /// @notice returns full token URI, including baseURI and token metadata URI\\n /// @param tokenId The token id to get URI for\\n /// @return tokenURI the URI of the token\\n function uri(uint256 tokenId)\\n public\\n view\\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\\n returns (string memory)\\n {\\n return ERC1155URIStorageUpgradeable.uri(tokenId);\\n }\\n\\n /// @dev Needed for meta transactions (see EIP-2771)\\n function _msgSender()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (address)\\n {\\n return ERC2771HandlerUpgradeable._msgSender();\\n }\\n\\n /// @dev Needed for meta transactions (see EIP-2771)\\n function _msgData()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\\n returns (bytes calldata)\\n {\\n return ERC2771HandlerUpgradeable._msgData();\\n }\\n\\n /// @dev Sets `baseURI` as the `_baseURI` for all tokens\\n function _setBaseURI(string memory baseURI) internal virtual override {\\n super._setBaseURI(baseURI);\\n emit BaseURISet(baseURI);\\n }\\n\\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\\n /// @param from address from which tokens are transfered.\\n /// @param to address to which the token will be transfered.\\n /// @param id the token type transfered.\\n /// @param value amount of token transfered.\\n /// @param data additional data accompanying the transfer.\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 id,\\n uint256 value,\\n bytes memory data\\n ) public override onlyAllowedOperator(from) {\\n super._safeTransferFrom(from, to, id, value, data);\\n }\\n\\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\\n /// @param from address from which tokens are transfered.\\n /// @param to address to which the token will be transfered.\\n /// @param ids ids of each token type transfered.\\n /// @param values amount of each token type transfered.\\n /// @param data additional data accompanying the transfer.\\n function safeBatchTransferFrom(\\n address from,\\n address to,\\n uint256[] memory ids,\\n uint256[] memory values,\\n bytes memory data\\n ) public override onlyAllowedOperator(from) {\\n super._safeBatchTransferFrom(from, to, ids, values, data);\\n }\\n\\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\\n /// @param approved whether to approve or revoke\\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\\n super._setApprovalForAll(_msgSender(), operator, approved);\\n }\\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\\n }\\n\\n /// @notice Query if a contract implements interface `id`.\\n /// @param interfaceId the interface identifier, as specified in ERC-165.\\n /// @return `true` if the contract implements `interfaceId`.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\\n returns (bool)\\n {\\n return super.supportsInterface(interfaceId);\\n }\\n\\n /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.\\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\\n /// @param subscribe bool to signify subscription \\\"true\\\"\\\" or to copy the list \\\"false\\\".\\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\\n external\\n onlyRole(DEFAULT_ADMIN_ROLE)\\n {\\n require(subscriptionOrRegistrantToCopy != address(0), \\\"Catalyst: Zero address\\\");\\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\\n }\\n\\n /// @notice sets filter registry address\\n /// @param registry the address of the registry\\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n require(registry != address(0), \\\"Catalyst: Zero address\\\");\\n OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);\\n emit OperatorRegistrySet(registry);\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x05885ab02e4879b85ec98c45dceeb98f11987566e13cef18fdab1c72abc3ad31\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity 0.8.18;\\n\\ninterface ICatalyst {\\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\\n\\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\\n event NewCatalystTypeAdded(uint256 catalystId);\\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\\n event BaseURISet(string baseURI);\\n event OperatorRegistrySet(address indexed registry);\\n\\n /// @notice Mints a new token, limited to MINTER_ROLE only\\n /// @param to The address that will own the minted token\\n /// @param id The token id to mint\\n /// @param amount The amount to be minted\\n function mint(\\n address to,\\n uint256 id,\\n uint256 amount\\n ) external;\\n\\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\\n /// @param to The address that will own the minted tokens\\n /// @param ids The token ids to mint\\n /// @param amounts The amounts to be minted per token id\\n function mintBatch(\\n address to,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external;\\n\\n /// @notice Burns a specified amount of tokens from a specific address\\n /// @param account The address to burn from\\n /// @param id The token id to burn\\n /// @param amount The amount to be burned\\n function burnFrom(\\n address account,\\n uint256 id,\\n uint256 amount\\n ) external;\\n\\n /// @notice Burns a batch of tokens from a specific address\\n /// @param account The address to burn from\\n /// @param ids The token ids to burn\\n /// @param amounts The amounts to be burned\\n function burnBatchFrom(\\n address account,\\n uint256[] memory ids,\\n uint256[] memory amounts\\n ) external;\\n\\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\\n /// @param ipfsCID The royalty bps for the catalyst\\n function addNewCatalystType(string memory ipfsCID) external;\\n\\n /// @notice Set a new URI for specific tokenid\\n /// @param tokenId The token id to set URI for\\n /// @param metadataHash The new URI\\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\\n\\n /// @notice Set a new base URI\\n /// @param baseURI The new base URI\\n function setBaseURI(string memory baseURI) external;\\n}\\n\",\"keccak256\":\"0x4dec39e4b662c4b51f0f828f1b8ea01c873c8a0a18a7c17bc5497f557ceff101\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\nabstract contract ERC2771HandlerAbstract {\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function isTrustedForwarder(address forwarder) external view returns (bool) {\\n return _isTrustedForwarder(forwarder);\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual returns (address sender) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n // The assembly code is more direct than the Solidity version using `abi.decode`.\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\\n }\\n } else {\\n sender = msg.sender;\\n }\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual returns (bytes calldata) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n return msg.data[:msg.data.length - 20];\\n } else {\\n return msg.data;\\n }\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n /// @dev this function must be IMPLEMENTED\\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xc4f349865ea7146f51b69f1edacdef60e0a2a7cf4dab538a5ae53ee9a0036231\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {ERC2771HandlerAbstract} from \\\"./ERC2771HandlerAbstract.sol\\\";\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\\n address private _trustedForwarder;\\n\\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\\n /// @param oldTrustedForwarder old trusted forwarder\\n /// @param newTrustedForwarder new trusted forwarder\\n /// @param operator the sender of the transaction\\n event TrustedForwarderSet(\\n address indexed oldTrustedForwarder,\\n address indexed newTrustedForwarder,\\n address indexed operator\\n );\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\\n __ERC2771Handler_init_unchained(forwarder);\\n }\\n\\n /// @notice initialize the trusted forwarder address\\n /// @param forwarder trusted forwarder address or zero to disable it\\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\\n _setTrustedForwarder(forwarder);\\n }\\n\\n /// @notice return the address of the trusted forwarder\\n /// @return return the address of the trusted forwarder\\n function getTrustedForwarder() external view returns (address) {\\n return _trustedForwarder;\\n }\\n\\n /// @notice set the address of the trusted forwarder\\n /// @param newForwarder the address of the new forwarder.\\n function _setTrustedForwarder(address newForwarder) internal virtual {\\n require(newForwarder != _trustedForwarder, \\\"ERC2771HandlerUpgradeable: forwarder already set\\\");\\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\\n _trustedForwarder = newForwarder;\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\\n return forwarder == _trustedForwarder;\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual override returns (address sender) {\\n return super._msgSender();\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual override returns (bytes calldata) {\\n return super._msgData();\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf9767f843906800128ee86bd89bc2088e8f1b633ed4c800f477beb4e604f81de\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {IOperatorFilterRegistry} from \\\"./interfaces/IOperatorFilterRegistry.sol\\\";\\nimport {ContextUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\\\";\\n\\n///@title OperatorFiltererUpgradeable\\n///@author The Sandbox\\n///@notice This contract would subscribe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's address could be set using a setter which could be implemented in inheriting contract\\nabstract contract OperatorFiltererUpgradeable is Initializable, ContextUpgradeable {\\n event OperatorFilterRegistrySet(address indexed registry);\\n\\n IOperatorFilterRegistry private operatorFilterRegistry;\\n\\n // solhint-disable-next-line func-name-mixedcase\\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\\n // order for the modifier to filter addresses.\\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\\n }\\n\\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\\n if (address(operatorFilterRegistry).code.length > 0) {\\n if (!operatorFilterRegistry.isRegistered(address(this))) {\\n if (subscribe) {\\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\\n } else {\\n if (subscriptionOrRegistrantToCopy != address(0)) {\\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\\n } else {\\n operatorFilterRegistry.register(address(this));\\n }\\n }\\n }\\n }\\n }\\n\\n modifier onlyAllowedOperator(address from) virtual {\\n // Check registry code length to facilitate testing in environments without a deployed registry.\\n if (address(operatorFilterRegistry).code.length > 0) {\\n // Allow spending tokens from addresses with balance\\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\\n // from an EOA.\\n if (from == _msgSender()) {\\n _;\\n return;\\n }\\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), _msgSender())) {\\n revert(\\\"Operator Not Allowed\\\");\\n }\\n }\\n _;\\n }\\n\\n modifier onlyAllowedOperatorApproval(address operator) virtual {\\n // Check registry code length to facilitate testing in environments without a deployed registry.\\n if (address(operatorFilterRegistry).code.length > 0) {\\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\\n revert(\\\"Operator Not Allowed\\\");\\n }\\n }\\n _;\\n }\\n\\n /// @notice returns the operator filter registry.\\n /// @return operatorFilterRegistryAddress address of operator filter registry contract.\\n function getOperatorFilterRegistry() external view returns (IOperatorFilterRegistry operatorFilterRegistryAddress) {\\n return _getOperatorFilterRegistry();\\n }\\n\\n /// @notice internal method to set the operator filter registry\\n /// @param registry address the registry.\\n function _setOperatorFilterRegistry(address registry) internal {\\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\\n emit OperatorFilterRegistrySet(registry);\\n }\\n\\n /// @notice internal method to get the operator filter registry.\\n function _getOperatorFilterRegistry()\\n internal\\n view\\n returns (IOperatorFilterRegistry operatorFilterRegistryAddress)\\n {\\n return operatorFilterRegistry;\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xbd7e2d8ee93a31af7057933a0ea415f7c1ab90dbfbb8e41085ef23ed98ead3af\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title IOperatorFilterRegistry\\n/// @notice Interface for managing operators and filtering.\\ninterface IOperatorFilterRegistry {\\n ///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\\n /// true if supplied registrant address is not registered.\\n function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed);\\n\\n ///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\\n function register(address registrant) external;\\n\\n ///@notice Registers an address with the registry and \\\"subscribes\\\" to another address's filtered operators and codeHashes.\\n function registerAndSubscribe(address registrant, address subscription) external;\\n\\n ///@notice Registers an address with the registry and copies the filtered operators and codeHashes from another\\n /// address without subscribing.\\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\\n\\n ///@notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\\n /// Note that this does not remove any filtered addresses or codeHashes.\\n /// Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\\n function unregister(address addr) external;\\n\\n ///@notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\\n function updateOperator(\\n address registrant,\\n address operator,\\n bool filtered\\n ) external;\\n\\n ///@notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\\n function updateOperators(\\n address registrant,\\n address[] calldata operators,\\n bool filtered\\n ) external;\\n\\n ///@notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\\n function updateCodeHash(\\n address registrant,\\n bytes32 codehash,\\n bool filtered\\n ) external;\\n\\n ///@notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\\n function updateCodeHashes(\\n address registrant,\\n bytes32[] calldata codeHashes,\\n bool filtered\\n ) external;\\n\\n ///@notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\\n /// subscription if present.\\n /// Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\\n /// subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\\n /// used.\\n function subscribe(address registrant, address registrantToSubscribe) external;\\n\\n ///@notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\\n function unsubscribe(address registrant, bool copyExistingEntries) external;\\n\\n ///@notice Get the subscription address of a given registrant, if any.\\n function subscriptionOf(address addr) external returns (address registrant);\\n\\n ///@notice Get the set of addresses subscribed to a given registrant.\\n /// Note that order is not guaranteed as updates are made.\\n function subscribers(address registrant) external returns (address[] memory subscribersList);\\n\\n ///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\\n /// Note that order is not guaranteed as updates are made.\\n function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress);\\n\\n ///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\\n function copyEntriesOf(address registrant, address registrantToCopy) external;\\n\\n ///@notice Returns true if operator is filtered by a given address or its subscription.\\n function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered);\\n\\n ///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered);\\n\\n ///@notice Returns true if a codeHash is filtered by a given address or its subscription.\\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered);\\n\\n ///@notice Returns a list of filtered operators for a given address or its subscription.\\n function filteredOperators(address addr) external returns (address[] memory operatorList);\\n\\n ///@notice Returns the set of filtered codeHashes for a given address or its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList);\\n\\n ///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\\n /// its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredOperatorAt(address registrant, uint256 index) external returns (address operator);\\n\\n ///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\\n /// its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash);\\n\\n ///@notice Returns true if an address has registered\\n function isRegistered(address addr) external returns (bool registered);\\n\\n ///@dev Convenience method to compute the code hash of an arbitrary contract\\n function codeHashOf(address addr) external returns (bytes32 codeHash);\\n}\\n\",\"keccak256\":\"0x3954f1465330c8645891a1d566723f9804515632be2025edd02b00a0e53d2f30\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC2981Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\\\";\\nimport {IRoyaltyManager} from \\\"./interfaces/IRoyaltyManager.sol\\\";\\nimport {\\n ERC165Upgradeable,\\n IERC165Upgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\\\";\\n\\n/// @title RoyaltyDistributor\\n/// @author The Sandbox\\n/// @notice Contract for distributing royalties based on the ERC2981 standard.\\nabstract contract RoyaltyDistributor is IERC2981Upgradeable, ERC165Upgradeable {\\n event RoyaltyManagerSet(address indexed _royaltyManager);\\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\\n IRoyaltyManager private royaltyManager;\\n\\n // solhint-disable-next-line func-name-mixedcase\\n function __RoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing {\\n _setRoyaltyManager(_royaltyManager);\\n __ERC165_init_unchained();\\n }\\n\\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\\n /// @param _salePrice the price of token on which the royalty is calculated\\n /// @return receiver the receiver of royalty\\n /// @return royaltyAmount the amount of royalty\\n function royaltyInfo(\\n uint256, /*_tokenId */\\n uint256 _salePrice\\n ) external view returns (address receiver, uint256 royaltyAmount) {\\n uint16 royaltyBps;\\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\\n return (receiver, royaltyAmount);\\n }\\n\\n /// @notice Query if a contract implements interface `id`.\\n /// @param interfaceId the interface identifier, as specified in ERC-165.\\n /// @return isSupported `true` if the contract implements `id`.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(ERC165Upgradeable, IERC165Upgradeable)\\n returns (bool isSupported)\\n {\\n return (interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId));\\n }\\n\\n /// @notice returns the royalty manager\\n /// @return royaltyManagerAddress address of royalty manager contract.\\n function getRoyaltyManager() external view returns (IRoyaltyManager royaltyManagerAddress) {\\n return royaltyManager;\\n }\\n\\n /// @notice set royalty manager\\n /// @param _royaltyManager address of royalty manager to set\\n function _setRoyaltyManager(address _royaltyManager) internal {\\n royaltyManager = IRoyaltyManager(_royaltyManager);\\n emit RoyaltyManagerSet(_royaltyManager);\\n }\\n\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x234d5b2df36f3a7dce1d07e07096e4772223811aa32f6f21d9024276252aacfa\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Recipient} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\n\\n/// @title IRoyaltyManager\\n/// @notice interface for RoyaltyManager Contract\\ninterface IRoyaltyManager {\\n event RecipientSet(address indexed commonRecipient);\\n\\n event SplitSet(uint16 commonSplit);\\n\\n event RoyaltySet(uint16 royaltyBps, address indexed contractAddress);\\n\\n event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder);\\n\\n event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress);\\n\\n ///@notice sets the common recipient\\n ///@param _commonRecipient is the common recipient for all the splitters\\n function setRecipient(address payable _commonRecipient) external;\\n\\n ///@notice sets the common split\\n ///@param commonSplit split for the common recipient\\n function setSplit(uint16 commonSplit) external;\\n\\n ///@notice to be called by the splitters to get the common recipient and split\\n ///@return recipient which has the common recipient and split\\n function getCommonRecipient() external view returns (Recipient memory recipient);\\n\\n ///@notice returns the amount of basis points allocated to the creator\\n ///@return creatorSplit the share of creator in bps\\n function getCreatorSplit() external view returns (uint16 creatorSplit);\\n\\n ///@notice returns the commonRecipient and EIP2981 royalty split\\n ///@return recipient address of common royalty recipient\\n ///@return royaltySplit contract EIP2981 royalty bps\\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit);\\n\\n ///@notice deploys splitter for creator\\n ///@param creator the address of the creator\\n ///@param recipient the wallet of the recipient where they would receive their royalty\\n ///@return creatorSplitterAddress splitter's address deployed for creator\\n function deploySplitter(address creator, address payable recipient)\\n external\\n returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the address of splitter of a creator.\\n ///@param creator the address of the creator\\n ///@return creatorSplitterAddress splitter's address deployed for a creator\\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the EIP2981 royalty split\\n ///@param _contractAddress the address of the contract for which the royalty is required\\n ///@return royaltyBps royalty bps of the contract\\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\\n\\n ///@notice sets the trustedForwarder address to be used by the splitters\\n ///@param _newForwarder is the new trusted forwarder address\\n function setTrustedForwarder(address _newForwarder) external;\\n\\n ///@notice get the current trustedForwarder address\\n ///@return trustedForwarder address of current trusted Forwarder\\n function getTrustedForwarder() external view returns (address trustedForwarder);\\n}\\n\",\"keccak256\":\"0x5e8e149845df288a5d0ddfa00407ebda15d024e8caf1057822670a5232fee93f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61474680620000f36000396000f3fe608060405234801561001057600080fd5b50600436106102765760003560e01c8063572b6c0511610160578063bd85b039116100d8578063da7422281161008c578063f242432a11610071578063f242432a146105fb578063f3bdecc11461060e578063f5298aca1461062157600080fd5b8063da742228146105ac578063e985e9c5146105bf57600080fd5b8063d5391393116100bd578063d53913931461055f578063d547741f14610586578063d81d0a151461059957600080fd5b8063bd85b0391461052d578063ce1b815f1461054d57600080fd5b806391d148541161012f5780639d28fb86116101145780639d28fb86146104ff578063a217fddf14610512578063a22cb4651461051a57600080fd5b806391d14854146104b35780639a1b2fb4146104ed57600080fd5b8063572b6c05146104705780636b20c4541461048357806371e0276c14610496578063791459ea146104a057600080fd5b80632a55205a116101f35780634e1273f4116101c257806350c821b0116101a757806350c821b01461042a578063512c97e91461044a57806355f804b31461045d57600080fd5b80634e1273f4146103e85780634f558e791461040857600080fd5b80632a55205a1461037d5780632eb2c2d6146103af5780632f2ff15d146103c257806336568abe146103d557600080fd5b8063156e29f61161024a57806320820ec31161022f57806320820ec31461031f578063248a9ca314610332578063282c51f31461035657600080fd5b8063156e29f6146102f95780631a87b2771461030c57600080fd5b8062fdd58e1461027b57806301ffc9a7146102a15780630e89341c146102c4578063124d91e5146102e4575b600080fd5b61028e610289366004613a94565b610634565b6040519081526020015b60405180910390f35b6102b46102af366004613ad6565b6106e2565b6040519015158152602001610298565b6102d76102d2366004613af3565b6106ed565b6040516102989190613b5c565b6102f76102f2366004613b6f565b6106f8565b005b6102f7610307366004613b6f565b610733565b6102f761031a366004613c5b565b6107df565b6102f761032d366004613d2d565b610896565b61028e610340366004613af3565b600090815261015f602052604090206001015490565b61028e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61039061038b366004613da3565b6108cb565b604080516001600160a01b039093168352602083019190915201610298565b6102f76103bd366004613dc5565b610971565b6102f76103d0366004613e73565b610aa3565b6102f76103e3366004613e73565b610ace565b6103fb6103f6366004613ea3565b610b6a565b6040516102989190613fa1565b6102b4610416366004613af3565b600090815260c96020526040902054151590565b610432610ca8565b6040516001600160a01b039091168152602001610298565b6102f7610458366004613fb4565b610cc2565b6102f761046b366004613c5b565b610d88565b6102b461047e366004613ff1565b610e28565b6102f7610491366004613d2d565b610e43565b61028e6101f55481565b6102f76104ae36600461401c565b610eee565b6102b46104c1366004613e73565b600091825261015f602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6101c3546001600160a01b0316610432565b6102f761050d366004613ff1565b610f59565b61028e600081565b6102f761052836600461401c565b610ffb565b61028e61053b366004613af3565b600090815260c9602052604090205490565b61012d546001600160a01b0316610432565b61028e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6102f7610594366004613e73565b6110fc565b6102f76105a7366004613d2d565b611122565b6102f76105ba366004613ff1565b611217565b6102b46105cd36600461404a565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205460ff1690565b6102f7610609366004614078565b611281565b6102f761061c3660046140e1565b6113a6565b6102f761062f366004613b6f565b6117fa565b60006001600160a01b0383166106b75760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e65720000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526065602090815260408083206001600160a01b03861684529091529020545b92915050565b60006106dc826118a5565b60606106dc826118e3565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610722816119c3565b61072d8484846119d7565b50505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661075d816119c3565b8260008111801561077157506101f5548111155b6107bd5760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a20696e76616c696420636174616c79737420696400000060448201526064016106ae565b6107d885858560405180602001604052806000815250611bae565b5050505050565b60006107ea816119c3565b815160000361083b5760405162461bcd60e51b815260206004820152601b60248201527f436174616c7973743a204349442063616e7420626520656d707479000000000060448201526064016106ae565b60006101f56000815461084d90614233565b9182905550905061085e8184611cf1565b6040518181527f0fc221b41b73e1c4f9d65566cf090e650d0246fb5c0434a32e9b313a39636d169060200160405180910390a1505050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486108c0816119c3565b61072d848484611d4e565b60008060006101c360009054906101000a90046001600160a01b03166001600160a01b031663a86a28d16040518163ffffffff1660e01b81526004016040805180830381865afa158015610923573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610947919061424d565b909350905061271061095d61ffff831686614283565b610967919061429a565b9150509250929050565b6101915485906001600160a01b03163b15610a8e5761098e611fe0565b6001600160a01b0316816001600160a01b0316036109b8576109b38686868686611fea565b610a9b565b610191546001600160a01b031663c6171134306109d3611fe0565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4291906142bc565b610a8e5760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016106ae565b610a9b8686868686611fea565b505050505050565b600082815261015f6020526040902060010154610abf816119c3565b610ac98383612287565b505050565b610ad6611fe0565b6001600160a01b0316816001600160a01b031614610b5c5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016106ae565b610b66828261232c565b5050565b60608151835114610be35760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016106ae565b6000835167ffffffffffffffff811115610bff57610bff613ba4565b604051908082528060200260200182016040528015610c28578160200160208202803683370190505b50905060005b8451811015610ca057610c73858281518110610c4c57610c4c6142d9565b6020026020010151858381518110610c6657610c666142d9565b6020026020010151610634565b828281518110610c8557610c856142d9565b6020908102919091010152610c9981614233565b9050610c2e565b509392505050565b6000610cbd610191546001600160a01b031690565b905090565b6000610ccd816119c3565b82600081118015610ce157506101f5548111155b610d2d5760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a20696e76616c696420636174616c79737420696400000060448201526064016106ae565b8251600003610d7e5760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a204d65746164617461206861736820656d70747900000060448201526064016106ae565b61072d8484611cf1565b6000610d93816119c3565b8151600003610de45760405162461bcd60e51b815260206004820152601360248201527f436174616c7973743a2055524920656d7074790000000000000000000000000060448201526064016106ae565b610ded826123cf565b7ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f682604051610e1c9190613b5c565b60405180910390a15050565b60006106dc8261012d546001600160a01b0391821691161490565b610e4b611fe0565b6001600160a01b0316836001600160a01b03161480610e715750610e71836105cd611fe0565b610ee35760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016106ae565b610ac9838383611d4e565b6000610ef9816119c3565b6001600160a01b038316610f4f5760405162461bcd60e51b815260206004820152601660248201527f436174616c7973743a205a65726f20616464726573730000000000000000000060448201526064016106ae565b610ac98383612412565b6000610f64816119c3565b6001600160a01b038216610fba5760405162461bcd60e51b815260206004820152601660248201527f436174616c7973743a205a65726f20616464726573730000000000000000000060448201526064016106ae565b610fc3826125de565b6040516001600160a01b038316907fc6df119c56c99171b170652a3c4750ba46dcaacbdb3b7ab4847a9fa339659bd490600090a25050565b6101915482906001600160a01b03163b156110ea57610191546040517fc61711340000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0383811660248301529091169063c617113490604401602060405180830381865afa15801561107a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109e91906142bc565b6110ea5760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016106ae565b610ac96110f5611fe0565b8484612636565b600082815261015f6020526040902060010154611118816119c3565b610ac9838361232c565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661114c816119c3565b60005b83518110156111fb57600084828151811061116c5761116c6142d9565b602002602001015111801561119d57506101f554848281518110611192576111926142d9565b602002602001015111155b6111e95760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a20696e76616c696420636174616c79737420696400000060448201526064016106ae565b806111f381614233565b91505061114f565b5061072d8484846040518060200160405280600081525061272a565b6000611222816119c3565b6001600160a01b0382166112785760405162461bcd60e51b815260206004820152601660248201527f436174616c7973743a205a65726f20616464726573730000000000000000000060448201526064016106ae565b610b6682612927565b6101915485906001600160a01b03163b156113995761129e611fe0565b6001600160a01b0316816001600160a01b0316036112c3576109b38686868686612a23565b610191546001600160a01b031663c6171134306112de611fe0565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134d91906142bc565b6113995760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016106ae565b610a9b8686868686612a23565b600054610100900460ff16158080156113c65750600054600160ff909116105b806113e05750303b1580156113e0575060005460ff166001145b6114525760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106ae565b6000805460ff191660011790558015611475576000805461ff0019166101001790555b87516000036114c65760405162461bcd60e51b815260206004820152601360248201527f436174616c7973743a2055524920656d7074790000000000000000000000000060448201526064016106ae565b6001600160a01b03871661151c5760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20312d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b0386166115725760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20322d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b0385166115c85760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20332d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b03841661161e5760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20342d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b0382166116745760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20352d5a65726f2061646472657373000000000000000060448201526064016106ae565b61167d88612c16565b611685612c8a565b61168d612c8a565b611695612c8a565b61169d612cf7565b6116a687612d6a565b6116b1866001612dde565b6116ba886123cf565b6116c5600086612287565b6116ef7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a685612287565b6116f882612e81565b60005b83518110156117a957838181518110611716576117166142d9565b60200260200101515160000361176e5760405162461bcd60e51b815260206004820152601b60248201527f436174616c7973743a204349442063616e7420626520656d707479000000000060448201526064016106ae565b61179181858381518110611784576117846142d9565b6020026020010151611cf1565b6101f5819055806117a181614233565b9150506116fb565b5080156117f0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b611802611fe0565b6001600160a01b0316836001600160a01b031614806118285750611828836105cd611fe0565b61189a5760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016106ae565b610ac98383836119d7565b60006001600160e01b031982167f2a55205a0000000000000000000000000000000000000000000000000000000014806106dc57506106dc82612efd565b600081815260fc6020526040812080546060929190611901906142ef565b80601f016020809104026020016040519081016040528092919081815260200182805461192d906142ef565b801561197a5780601f1061194f5761010080835404028352916020019161197a565b820191906000526020600020905b81548152906001019060200180831161195d57829003601f168201915b5050505050905060008151116119985761199383612f3b565b6119bc565b60fb816040516020016119ac929190614329565b6040516020818303038152906040525b9392505050565b6119d4816119cf611fe0565b612fcf565b50565b6001600160a01b038316611a535760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b6000611a5d611fe0565b90506000611a6a84613045565b90506000611a7784613045565b9050611a9783876000858560405180602001604052806000815250613090565b60008581526065602090815260408083206001600160a01b038a16845290915290205484811015611b2f5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016106ae565b60008681526065602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090525b50505050505050565b6001600160a01b038416611c2a5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b6000611c34611fe0565b90506000611c4185613045565b90506000611c4e85613045565b9050611c5f83600089858589613090565b60008681526065602090815260408083206001600160a01b038b16845290915281208054879290611c919084906143b0565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611ba58360008989898961309e565b600082815260fc60205260409020611d098282614409565b50817f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b611d35846106ed565b604051611d429190613b5c565b60405180910390a25050565b6001600160a01b038316611dca5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b8051825114611e2c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016106ae565b6000611e36611fe0565b9050611e5681856000868660405180602001604052806000815250613090565b60005b8351811015611f73576000848281518110611e7657611e766142d9565b602002602001015190506000848381518110611e9457611e946142d9565b60209081029190910181015160008481526065835260408082206001600160a01b038c168352909352919091205490915081811015611f3a5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016106ae565b60009283526065602090815260408085206001600160a01b038b1686529091529092209103905580611f6b81614233565b915050611e59565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611fc49291906144c9565b60405180910390a460408051602081019091526000905261072d565b6000610cbd61328a565b815183511461204c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016106ae565b6001600160a01b0384166120c85760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ae565b60006120d2611fe0565b90506120e2818787878787613090565b60005b8451811015612221576000858281518110612102576121026142d9565b602002602001015190506000858381518110612120576121206142d9565b60209081029190910181015160008481526065835260408082206001600160a01b038e1683529093529190912054909150818110156121c75760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016106ae565b60008381526065602090815260408083206001600160a01b038e8116855292528083208585039055908b168252812080548492906122069084906143b0565b925050819055505050508061221a90614233565b90506120e5565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516122719291906144c9565b60405180910390a4610a9b818787878787613294565b600082815261015f602090815260408083206001600160a01b038516845290915290205460ff16610b6657600082815261015f602090815260408083206001600160a01b03851684529091529020805460ff191660011790556122e8611fe0565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815261015f602090815260408083206001600160a01b038516845290915290205460ff1615610b6657600082815261015f602090815260408083206001600160a01b03851684529091529020805460ff1916905561238b611fe0565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6123d8816133d7565b7ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6816040516124079190613b5c565b60405180910390a150565b610191546001600160a01b03163b15610b6657610191546040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b039091169063c3c5a547906024016020604051808303816000875af1158015612489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ad91906142bc565b610b6657801561253357610191546040517f7d3e3dbe0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03848116602483015290911690637d3e3dbe906044015b600060405180830381600087803b15801561251f57600080fd5b505af1158015610a9b573d6000803e3d6000fd5b6001600160a01b0382161561259457610191546040517fa0af29030000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0384811660248301529091169063a0af290390604401612505565b610191546040517f4420e4860000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0390911690634420e48690602401612505565b610191805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517fe9919957d871eafd2de063f58e6c3015bdee186c8a161b85d6173122db2210f890600090a250565b816001600160a01b0316836001600160a01b0316036126bd5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016106ae565b6001600160a01b03838116600081815260666020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0384166127a65760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b81518351146128085760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016106ae565b6000612812611fe0565b905061282381600087878787613090565b60005b84518110156128bf57838181518110612841576128416142d9565b60200260200101516065600087848151811061285f5761285f6142d9565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002060008282546128a791906143b0565b909155508190506128b781614233565b915050612826565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516129109291906144c9565b60405180910390a46107d881600087878787613294565b61012d546001600160a01b03908116908216036129ac5760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c7265616479207365740000000000000000000000000000000060648201526084016106ae565b6129b4611fe0565b61012d546040516001600160a01b03928316928481169216907f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e590600090a461012d805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038416612a9f5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ae565b6000612aa9611fe0565b90506000612ab685613045565b90506000612ac385613045565b9050612ad3838989858589613090565b60008681526065602090815260408083206001600160a01b038c16845290915290205485811015612b6c5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016106ae565b60008781526065602090815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290612bab9084906143b0565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4612c0b848a8a8a8a8a61309e565b505050505050505050565b600054610100900460ff16612c815760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d4816133e3565b600054610100900460ff16612cf55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b565b600054610100900460ff16612d625760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b612cf5613457565b600054610100900460ff16612dd55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d4816134de565b600054610100900460ff16612e495760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b610191805473ffffffffffffffffffffffffffffffffffffffff19166daaeb6d7670e522a718067333cd4e179055610b668282612412565b600054610100900460ff16612eec5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b612ef581613552565b6119d4612c8a565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806106dc57506106dc826135aa565b606060678054612f4a906142ef565b80601f0160208091040260200160405190810160405280929190818152602001828054612f76906142ef565b8015612fc35780601f10612f9857610100808354040283529160200191612fc3565b820191906000526020600020905b815481529060010190602001808311612fa657829003601f168201915b50505050509050919050565b600082815261015f602090815260408083206001600160a01b038516845290915290205460ff16610b665761300381613645565b61300e836020613657565b60405160200161301f9291906144f7565b60408051601f198184030181529082905262461bcd60e51b82526106ae91600401613b5c565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061307f5761307f6142d9565b602090810291909101015292915050565b610a9b868686868686613880565b6001600160a01b0384163b15610a9b576040517ff23a6e610000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063f23a6e61906130fb9089908990889088908890600401614578565b6020604051808303816000875af1925050508015613136575060408051601f3d908101601f19168201909252613133918101906145bb565b60015b6131eb576131426145d8565b806308c379a00361317b57506131566145f3565b80613161575061317d565b8060405162461bcd60e51b81526004016106ae9190613b5c565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016106ae565b6001600160e01b031981167ff23a6e610000000000000000000000000000000000000000000000000000000014611ba55760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016106ae565b6000610cbd613a0e565b6001600160a01b0384163b15610a9b576040517fbc197c810000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063bc197c81906132f1908990899088908890889060040161469b565b6020604051808303816000875af192505050801561332c575060408051601f3d908101601f19168201909252613329918101906145bb565b60015b613338576131426145d8565b6001600160e01b031981167fbc197c810000000000000000000000000000000000000000000000000000000014611ba55760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016106ae565b60fb610b668282614409565b600054610100900460ff1661344e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d481613a63565b600054610100900460ff166134c25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b60408051602081019091526000815260fb906119d49082614409565b600054610100900460ff166135495760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d481612927565b6101c3805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de890600090a250565b60006001600160e01b031982167fd9b67a2600000000000000000000000000000000000000000000000000000000148061360d57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b806106dc57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146106dc565b60606106dc6001600160a01b03831660145b60606000613666836002614283565b6136719060026143b0565b67ffffffffffffffff81111561368957613689613ba4565b6040519080825280601f01601f1916602001820160405280156136b3576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106136ea576136ea6142d9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061374d5761374d6142d9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000613789846002614283565b6137949060016143b0565b90505b6001811115613831577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106137d5576137d56142d9565b1a60f81b8282815181106137eb576137eb6142d9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361382a816146f9565b9050613797565b5083156119bc5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106ae565b6001600160a01b0385166139075760005b8351811015613905578281815181106138ac576138ac6142d9565b602002602001015160c960008684815181106138ca576138ca6142d9565b6020026020010151815260200190815260200160002060008282546138ef91906143b0565b909155506138fe905081614233565b9050613891565b505b6001600160a01b038416610a9b5760005b8351811015611ba5576000848281518110613935576139356142d9565b602002602001015190506000848381518110613953576139536142d9565b60200260200101519050600060c96000848152602001908152602001600020549050818110156139eb5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c7900000000000000000000000000000000000000000000000060648201526084016106ae565b600092835260c9602052604090922091039055613a0781614233565b9050613918565b61012d546000906001600160a01b031633148015613a2d575060143610155b15613a5d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b50335b90565b6067610b668282614409565b6001600160a01b03811681146119d457600080fd5b8035613a8f81613a6f565b919050565b60008060408385031215613aa757600080fd5b8235613ab281613a6f565b946020939093013593505050565b6001600160e01b0319811681146119d457600080fd5b600060208284031215613ae857600080fd5b81356119bc81613ac0565b600060208284031215613b0557600080fd5b5035919050565b60005b83811015613b27578181015183820152602001613b0f565b50506000910152565b60008151808452613b48816020860160208601613b0c565b601f01601f19169290920160200192915050565b6020815260006119bc6020830184613b30565b600080600060608486031215613b8457600080fd5b8335613b8f81613a6f565b95602085013595506040909401359392505050565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff82111715613be057613be0613ba4565b6040525050565b600082601f830112613bf857600080fd5b813567ffffffffffffffff811115613c1257613c12613ba4565b604051613c296020601f19601f8501160182613bba565b818152846020838601011115613c3e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613c6d57600080fd5b813567ffffffffffffffff811115613c8457600080fd5b613c9084828501613be7565b949350505050565b600067ffffffffffffffff821115613cb257613cb2613ba4565b5060051b60200190565b600082601f830112613ccd57600080fd5b81356020613cda82613c98565b604051613ce78282613bba565b83815260059390931b8501820192828101915086841115613d0757600080fd5b8286015b84811015613d225780358352918301918301613d0b565b509695505050505050565b600080600060608486031215613d4257600080fd5b8335613d4d81613a6f565b9250602084013567ffffffffffffffff80821115613d6a57600080fd5b613d7687838801613cbc565b93506040860135915080821115613d8c57600080fd5b50613d9986828701613cbc565b9150509250925092565b60008060408385031215613db657600080fd5b50508035926020909101359150565b600080600080600060a08688031215613ddd57600080fd5b8535613de881613a6f565b94506020860135613df881613a6f565b9350604086013567ffffffffffffffff80821115613e1557600080fd5b613e2189838a01613cbc565b94506060880135915080821115613e3757600080fd5b613e4389838a01613cbc565b93506080880135915080821115613e5957600080fd5b50613e6688828901613be7565b9150509295509295909350565b60008060408385031215613e8657600080fd5b823591506020830135613e9881613a6f565b809150509250929050565b60008060408385031215613eb657600080fd5b823567ffffffffffffffff80821115613ece57600080fd5b818501915085601f830112613ee257600080fd5b81356020613eef82613c98565b604051613efc8282613bba565b83815260059390931b8501820192828101915089841115613f1c57600080fd5b948201945b83861015613f43578535613f3481613a6f565b82529482019490820190613f21565b96505086013592505080821115613f5957600080fd5b5061096785828601613cbc565b600081518084526020808501945080840160005b83811015613f9657815187529582019590820190600101613f7a565b509495945050505050565b6020815260006119bc6020830184613f66565b60008060408385031215613fc757600080fd5b82359150602083013567ffffffffffffffff811115613fe557600080fd5b61096785828601613be7565b60006020828403121561400357600080fd5b81356119bc81613a6f565b80151581146119d457600080fd5b6000806040838503121561402f57600080fd5b823561403a81613a6f565b91506020830135613e988161400e565b6000806040838503121561405d57600080fd5b823561406881613a6f565b91506020830135613e9881613a6f565b600080600080600060a0868803121561409057600080fd5b853561409b81613a6f565b945060208601356140ab81613a6f565b93506040860135925060608601359150608086013567ffffffffffffffff8111156140d557600080fd5b613e6688828901613be7565b600080600080600080600060e0888a0312156140fc57600080fd5b67ffffffffffffffff808935111561411357600080fd5b6141208a8a358b01613be7565b9750602089013561413081613a6f565b9650604089013561414081613a6f565b9550606089013561415081613a6f565b9450608089013561416081613a6f565b935060a08901358181111561417457600080fd5b8901601f81018b1361418557600080fd5b803561419081613c98565b60405161419d8282613bba565b80915082815260208101915060208360051b85010192508d8311156141c157600080fd5b602084015b838110156141fa5785813511156141dc57600080fd5b6141ec8f60208335880101613be7565b8352602092830192016141c6565b50809650505050505061420f60c08901613a84565b905092959891949750929550565b634e487b7160e01b600052601160045260246000fd5b600060001982036142465761424661421d565b5060010190565b6000806040838503121561426057600080fd5b825161426b81613a6f565b602084015190925061ffff81168114613e9857600080fd5b80820281158282048414176106dc576106dc61421d565b6000826142b757634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156142ce57600080fd5b81516119bc8161400e565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061430357607f821691505b60208210810361432357634e487b7160e01b600052602260045260246000fd5b50919050565b6000808454614337816142ef565b6001828116801561434f576001811461436457614393565b60ff1984168752821515830287019450614393565b8860005260208060002060005b8581101561438a5781548a820152908401908201614371565b50505082870194505b5050505083516143a7818360208801613b0c565b01949350505050565b808201808211156106dc576106dc61421d565b601f821115610ac957600081815260208120601f850160051c810160208610156143ea5750805b601f850160051c820191505b81811015610a9b578281556001016143f6565b815167ffffffffffffffff81111561442357614423613ba4565b6144378161443184546142ef565b846143c3565b602080601f83116001811461446c57600084156144545750858301515b600019600386901b1c1916600185901b178555610a9b565b600085815260208120601f198616915b8281101561449b5788860151825594840194600190910190840161447c565b50858210156144b95787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6040815260006144dc6040830185613f66565b82810360208401526144ee8185613f66565b95945050505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161452f816017850160208801613b0c565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161456c816028840160208801613b0c565b01602801949350505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526145b060a0830184613b30565b979650505050505050565b6000602082840312156145cd57600080fd5b81516119bc81613ac0565b600060033d1115613a605760046000803e5060005160e01c90565b600060443d10156146015790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff816024840111818411171561464f57505050505090565b82850191508151818111156146675750505050505090565b843d87010160208285010111156146815750505050505090565b61469060208286010187613bba565b509095945050505050565b60006001600160a01b03808816835280871660208401525060a060408301526146c760a0830186613f66565b82810360608401526146d98186613f66565b905082810360808401526146ed8185613b30565b98975050505050505050565b6000816147085761470861421d565b50600019019056fea2646970667358221220984fb4dae22ed4aba9db5e3346aea4e270846b068ed4e6f7516b7ee7d9257fdf64736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102765760003560e01c8063572b6c0511610160578063bd85b039116100d8578063da7422281161008c578063f242432a11610071578063f242432a146105fb578063f3bdecc11461060e578063f5298aca1461062157600080fd5b8063da742228146105ac578063e985e9c5146105bf57600080fd5b8063d5391393116100bd578063d53913931461055f578063d547741f14610586578063d81d0a151461059957600080fd5b8063bd85b0391461052d578063ce1b815f1461054d57600080fd5b806391d148541161012f5780639d28fb86116101145780639d28fb86146104ff578063a217fddf14610512578063a22cb4651461051a57600080fd5b806391d14854146104b35780639a1b2fb4146104ed57600080fd5b8063572b6c05146104705780636b20c4541461048357806371e0276c14610496578063791459ea146104a057600080fd5b80632a55205a116101f35780634e1273f4116101c257806350c821b0116101a757806350c821b01461042a578063512c97e91461044a57806355f804b31461045d57600080fd5b80634e1273f4146103e85780634f558e791461040857600080fd5b80632a55205a1461037d5780632eb2c2d6146103af5780632f2ff15d146103c257806336568abe146103d557600080fd5b8063156e29f61161024a57806320820ec31161022f57806320820ec31461031f578063248a9ca314610332578063282c51f31461035657600080fd5b8063156e29f6146102f95780631a87b2771461030c57600080fd5b8062fdd58e1461027b57806301ffc9a7146102a15780630e89341c146102c4578063124d91e5146102e4575b600080fd5b61028e610289366004613a94565b610634565b6040519081526020015b60405180910390f35b6102b46102af366004613ad6565b6106e2565b6040519015158152602001610298565b6102d76102d2366004613af3565b6106ed565b6040516102989190613b5c565b6102f76102f2366004613b6f565b6106f8565b005b6102f7610307366004613b6f565b610733565b6102f761031a366004613c5b565b6107df565b6102f761032d366004613d2d565b610896565b61028e610340366004613af3565b600090815261015f602052604090206001015490565b61028e7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61039061038b366004613da3565b6108cb565b604080516001600160a01b039093168352602083019190915201610298565b6102f76103bd366004613dc5565b610971565b6102f76103d0366004613e73565b610aa3565b6102f76103e3366004613e73565b610ace565b6103fb6103f6366004613ea3565b610b6a565b6040516102989190613fa1565b6102b4610416366004613af3565b600090815260c96020526040902054151590565b610432610ca8565b6040516001600160a01b039091168152602001610298565b6102f7610458366004613fb4565b610cc2565b6102f761046b366004613c5b565b610d88565b6102b461047e366004613ff1565b610e28565b6102f7610491366004613d2d565b610e43565b61028e6101f55481565b6102f76104ae36600461401c565b610eee565b6102b46104c1366004613e73565b600091825261015f602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6101c3546001600160a01b0316610432565b6102f761050d366004613ff1565b610f59565b61028e600081565b6102f761052836600461401c565b610ffb565b61028e61053b366004613af3565b600090815260c9602052604090205490565b61012d546001600160a01b0316610432565b61028e7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6102f7610594366004613e73565b6110fc565b6102f76105a7366004613d2d565b611122565b6102f76105ba366004613ff1565b611217565b6102b46105cd36600461404a565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205460ff1690565b6102f7610609366004614078565b611281565b6102f761061c3660046140e1565b6113a6565b6102f761062f366004613b6f565b6117fa565b60006001600160a01b0383166106b75760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e65720000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526065602090815260408083206001600160a01b03861684529091529020545b92915050565b60006106dc826118a5565b60606106dc826118e3565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610722816119c3565b61072d8484846119d7565b50505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661075d816119c3565b8260008111801561077157506101f5548111155b6107bd5760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a20696e76616c696420636174616c79737420696400000060448201526064016106ae565b6107d885858560405180602001604052806000815250611bae565b5050505050565b60006107ea816119c3565b815160000361083b5760405162461bcd60e51b815260206004820152601b60248201527f436174616c7973743a204349442063616e7420626520656d707479000000000060448201526064016106ae565b60006101f56000815461084d90614233565b9182905550905061085e8184611cf1565b6040518181527f0fc221b41b73e1c4f9d65566cf090e650d0246fb5c0434a32e9b313a39636d169060200160405180910390a1505050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a8486108c0816119c3565b61072d848484611d4e565b60008060006101c360009054906101000a90046001600160a01b03166001600160a01b031663a86a28d16040518163ffffffff1660e01b81526004016040805180830381865afa158015610923573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610947919061424d565b909350905061271061095d61ffff831686614283565b610967919061429a565b9150509250929050565b6101915485906001600160a01b03163b15610a8e5761098e611fe0565b6001600160a01b0316816001600160a01b0316036109b8576109b38686868686611fea565b610a9b565b610191546001600160a01b031663c6171134306109d3611fe0565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015610a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4291906142bc565b610a8e5760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016106ae565b610a9b8686868686611fea565b505050505050565b600082815261015f6020526040902060010154610abf816119c3565b610ac98383612287565b505050565b610ad6611fe0565b6001600160a01b0316816001600160a01b031614610b5c5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016106ae565b610b66828261232c565b5050565b60608151835114610be35760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016106ae565b6000835167ffffffffffffffff811115610bff57610bff613ba4565b604051908082528060200260200182016040528015610c28578160200160208202803683370190505b50905060005b8451811015610ca057610c73858281518110610c4c57610c4c6142d9565b6020026020010151858381518110610c6657610c666142d9565b6020026020010151610634565b828281518110610c8557610c856142d9565b6020908102919091010152610c9981614233565b9050610c2e565b509392505050565b6000610cbd610191546001600160a01b031690565b905090565b6000610ccd816119c3565b82600081118015610ce157506101f5548111155b610d2d5760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a20696e76616c696420636174616c79737420696400000060448201526064016106ae565b8251600003610d7e5760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a204d65746164617461206861736820656d70747900000060448201526064016106ae565b61072d8484611cf1565b6000610d93816119c3565b8151600003610de45760405162461bcd60e51b815260206004820152601360248201527f436174616c7973743a2055524920656d7074790000000000000000000000000060448201526064016106ae565b610ded826123cf565b7ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f682604051610e1c9190613b5c565b60405180910390a15050565b60006106dc8261012d546001600160a01b0391821691161490565b610e4b611fe0565b6001600160a01b0316836001600160a01b03161480610e715750610e71836105cd611fe0565b610ee35760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016106ae565b610ac9838383611d4e565b6000610ef9816119c3565b6001600160a01b038316610f4f5760405162461bcd60e51b815260206004820152601660248201527f436174616c7973743a205a65726f20616464726573730000000000000000000060448201526064016106ae565b610ac98383612412565b6000610f64816119c3565b6001600160a01b038216610fba5760405162461bcd60e51b815260206004820152601660248201527f436174616c7973743a205a65726f20616464726573730000000000000000000060448201526064016106ae565b610fc3826125de565b6040516001600160a01b038316907fc6df119c56c99171b170652a3c4750ba46dcaacbdb3b7ab4847a9fa339659bd490600090a25050565b6101915482906001600160a01b03163b156110ea57610191546040517fc61711340000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0383811660248301529091169063c617113490604401602060405180830381865afa15801561107a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109e91906142bc565b6110ea5760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016106ae565b610ac96110f5611fe0565b8484612636565b600082815261015f6020526040902060010154611118816119c3565b610ac9838361232c565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661114c816119c3565b60005b83518110156111fb57600084828151811061116c5761116c6142d9565b602002602001015111801561119d57506101f554848281518110611192576111926142d9565b602002602001015111155b6111e95760405162461bcd60e51b815260206004820152601d60248201527f436174616c7973743a20696e76616c696420636174616c79737420696400000060448201526064016106ae565b806111f381614233565b91505061114f565b5061072d8484846040518060200160405280600081525061272a565b6000611222816119c3565b6001600160a01b0382166112785760405162461bcd60e51b815260206004820152601660248201527f436174616c7973743a205a65726f20616464726573730000000000000000000060448201526064016106ae565b610b6682612927565b6101915485906001600160a01b03163b156113995761129e611fe0565b6001600160a01b0316816001600160a01b0316036112c3576109b38686868686612a23565b610191546001600160a01b031663c6171134306112de611fe0565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611329573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134d91906142bc565b6113995760405162461bcd60e51b815260206004820152601460248201527f4f70657261746f72204e6f7420416c6c6f77656400000000000000000000000060448201526064016106ae565b610a9b8686868686612a23565b600054610100900460ff16158080156113c65750600054600160ff909116105b806113e05750303b1580156113e0575060005460ff166001145b6114525760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106ae565b6000805460ff191660011790558015611475576000805461ff0019166101001790555b87516000036114c65760405162461bcd60e51b815260206004820152601360248201527f436174616c7973743a2055524920656d7074790000000000000000000000000060448201526064016106ae565b6001600160a01b03871661151c5760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20312d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b0386166115725760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20322d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b0385166115c85760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20332d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b03841661161e5760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20342d5a65726f2061646472657373000000000000000060448201526064016106ae565b6001600160a01b0382166116745760405162461bcd60e51b815260206004820152601860248201527f436174616c7973743a20352d5a65726f2061646472657373000000000000000060448201526064016106ae565b61167d88612c16565b611685612c8a565b61168d612c8a565b611695612c8a565b61169d612cf7565b6116a687612d6a565b6116b1866001612dde565b6116ba886123cf565b6116c5600086612287565b6116ef7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a685612287565b6116f882612e81565b60005b83518110156117a957838181518110611716576117166142d9565b60200260200101515160000361176e5760405162461bcd60e51b815260206004820152601b60248201527f436174616c7973743a204349442063616e7420626520656d707479000000000060448201526064016106ae565b61179181858381518110611784576117846142d9565b6020026020010151611cf1565b6101f5819055806117a181614233565b9150506116fb565b5080156117f0576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050505050565b611802611fe0565b6001600160a01b0316836001600160a01b031614806118285750611828836105cd611fe0565b61189a5760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f76656400000000000000000000000000000000000060648201526084016106ae565b610ac98383836119d7565b60006001600160e01b031982167f2a55205a0000000000000000000000000000000000000000000000000000000014806106dc57506106dc82612efd565b600081815260fc6020526040812080546060929190611901906142ef565b80601f016020809104026020016040519081016040528092919081815260200182805461192d906142ef565b801561197a5780601f1061194f5761010080835404028352916020019161197a565b820191906000526020600020905b81548152906001019060200180831161195d57829003601f168201915b5050505050905060008151116119985761199383612f3b565b6119bc565b60fb816040516020016119ac929190614329565b6040516020818303038152906040525b9392505050565b6119d4816119cf611fe0565b612fcf565b50565b6001600160a01b038316611a535760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b6000611a5d611fe0565b90506000611a6a84613045565b90506000611a7784613045565b9050611a9783876000858560405180602001604052806000815250613090565b60008581526065602090815260408083206001600160a01b038a16845290915290205484811015611b2f5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016106ae565b60008681526065602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090525b50505050505050565b6001600160a01b038416611c2a5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b6000611c34611fe0565b90506000611c4185613045565b90506000611c4e85613045565b9050611c5f83600089858589613090565b60008681526065602090815260408083206001600160a01b038b16845290915281208054879290611c919084906143b0565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4611ba58360008989898961309e565b600082815260fc60205260409020611d098282614409565b50817f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b611d35846106ed565b604051611d429190613b5c565b60405180910390a25050565b6001600160a01b038316611dca5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b8051825114611e2c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016106ae565b6000611e36611fe0565b9050611e5681856000868660405180602001604052806000815250613090565b60005b8351811015611f73576000848281518110611e7657611e766142d9565b602002602001015190506000848381518110611e9457611e946142d9565b60209081029190910181015160008481526065835260408082206001600160a01b038c168352909352919091205490915081811015611f3a5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e63650000000000000000000000000000000000000000000000000000000060648201526084016106ae565b60009283526065602090815260408085206001600160a01b038b1686529091529092209103905580611f6b81614233565b915050611e59565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611fc49291906144c9565b60405180910390a460408051602081019091526000905261072d565b6000610cbd61328a565b815183511461204c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016106ae565b6001600160a01b0384166120c85760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ae565b60006120d2611fe0565b90506120e2818787878787613090565b60005b8451811015612221576000858281518110612102576121026142d9565b602002602001015190506000858381518110612120576121206142d9565b60209081029190910181015160008481526065835260408082206001600160a01b038e1683529093529190912054909150818110156121c75760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016106ae565b60008381526065602090815260408083206001600160a01b038e8116855292528083208585039055908b168252812080548492906122069084906143b0565b925050819055505050508061221a90614233565b90506120e5565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516122719291906144c9565b60405180910390a4610a9b818787878787613294565b600082815261015f602090815260408083206001600160a01b038516845290915290205460ff16610b6657600082815261015f602090815260408083206001600160a01b03851684529091529020805460ff191660011790556122e8611fe0565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815261015f602090815260408083206001600160a01b038516845290915290205460ff1615610b6657600082815261015f602090815260408083206001600160a01b03851684529091529020805460ff1916905561238b611fe0565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6123d8816133d7565b7ff9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6816040516124079190613b5c565b60405180910390a150565b610191546001600160a01b03163b15610b6657610191546040517fc3c5a5470000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b039091169063c3c5a547906024016020604051808303816000875af1158015612489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124ad91906142bc565b610b6657801561253357610191546040517f7d3e3dbe0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03848116602483015290911690637d3e3dbe906044015b600060405180830381600087803b15801561251f57600080fd5b505af1158015610a9b573d6000803e3d6000fd5b6001600160a01b0382161561259457610191546040517fa0af29030000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0384811660248301529091169063a0af290390604401612505565b610191546040517f4420e4860000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b0390911690634420e48690602401612505565b610191805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517fe9919957d871eafd2de063f58e6c3015bdee186c8a161b85d6173122db2210f890600090a250565b816001600160a01b0316836001600160a01b0316036126bd5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016106ae565b6001600160a01b03838116600081815260666020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0384166127a65760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106ae565b81518351146128085760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016106ae565b6000612812611fe0565b905061282381600087878787613090565b60005b84518110156128bf57838181518110612841576128416142d9565b60200260200101516065600087848151811061285f5761285f6142d9565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b0316815260200190815260200160002060008282546128a791906143b0565b909155508190506128b781614233565b915050612826565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516129109291906144c9565b60405180910390a46107d881600087878787613294565b61012d546001600160a01b03908116908216036129ac5760405162461bcd60e51b815260206004820152603060248201527f4552433237373148616e646c65725570677261646561626c653a20666f72776160448201527f7264657220616c7265616479207365740000000000000000000000000000000060648201526084016106ae565b6129b4611fe0565b61012d546040516001600160a01b03928316928481169216907f8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e590600090a461012d805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038416612a9f5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016106ae565b6000612aa9611fe0565b90506000612ab685613045565b90506000612ac385613045565b9050612ad3838989858589613090565b60008681526065602090815260408083206001600160a01b038c16845290915290205485811015612b6c5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201527f72207472616e736665720000000000000000000000000000000000000000000060648201526084016106ae565b60008781526065602090815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290612bab9084906143b0565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4612c0b848a8a8a8a8a61309e565b505050505050505050565b600054610100900460ff16612c815760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d4816133e3565b600054610100900460ff16612cf55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b565b600054610100900460ff16612d625760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b612cf5613457565b600054610100900460ff16612dd55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d4816134de565b600054610100900460ff16612e495760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b610191805473ffffffffffffffffffffffffffffffffffffffff19166daaeb6d7670e522a718067333cd4e179055610b668282612412565b600054610100900460ff16612eec5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b612ef581613552565b6119d4612c8a565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806106dc57506106dc826135aa565b606060678054612f4a906142ef565b80601f0160208091040260200160405190810160405280929190818152602001828054612f76906142ef565b8015612fc35780601f10612f9857610100808354040283529160200191612fc3565b820191906000526020600020905b815481529060010190602001808311612fa657829003601f168201915b50505050509050919050565b600082815261015f602090815260408083206001600160a01b038516845290915290205460ff16610b665761300381613645565b61300e836020613657565b60405160200161301f9291906144f7565b60408051601f198184030181529082905262461bcd60e51b82526106ae91600401613b5c565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061307f5761307f6142d9565b602090810291909101015292915050565b610a9b868686868686613880565b6001600160a01b0384163b15610a9b576040517ff23a6e610000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063f23a6e61906130fb9089908990889088908890600401614578565b6020604051808303816000875af1925050508015613136575060408051601f3d908101601f19168201909252613133918101906145bb565b60015b6131eb576131426145d8565b806308c379a00361317b57506131566145f3565b80613161575061317d565b8060405162461bcd60e51b81526004016106ae9190613b5c565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016106ae565b6001600160e01b031981167ff23a6e610000000000000000000000000000000000000000000000000000000014611ba55760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016106ae565b6000610cbd613a0e565b6001600160a01b0384163b15610a9b576040517fbc197c810000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063bc197c81906132f1908990899088908890889060040161469b565b6020604051808303816000875af192505050801561332c575060408051601f3d908101601f19168201909252613329918101906145bb565b60015b613338576131426145d8565b6001600160e01b031981167fbc197c810000000000000000000000000000000000000000000000000000000014611ba55760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a6563746560448201527f6420746f6b656e7300000000000000000000000000000000000000000000000060648201526084016106ae565b60fb610b668282614409565b600054610100900460ff1661344e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d481613a63565b600054610100900460ff166134c25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b60408051602081019091526000815260fb906119d49082614409565b600054610100900460ff166135495760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b60648201526084016106ae565b6119d481612927565b6101c3805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de890600090a250565b60006001600160e01b031982167fd9b67a2600000000000000000000000000000000000000000000000000000000148061360d57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b806106dc57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146106dc565b60606106dc6001600160a01b03831660145b60606000613666836002614283565b6136719060026143b0565b67ffffffffffffffff81111561368957613689613ba4565b6040519080825280601f01601f1916602001820160405280156136b3576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106136ea576136ea6142d9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061374d5761374d6142d9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000613789846002614283565b6137949060016143b0565b90505b6001811115613831577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106137d5576137d56142d9565b1a60f81b8282815181106137eb576137eb6142d9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361382a816146f9565b9050613797565b5083156119bc5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106ae565b6001600160a01b0385166139075760005b8351811015613905578281815181106138ac576138ac6142d9565b602002602001015160c960008684815181106138ca576138ca6142d9565b6020026020010151815260200190815260200160002060008282546138ef91906143b0565b909155506138fe905081614233565b9050613891565b505b6001600160a01b038416610a9b5760005b8351811015611ba5576000848281518110613935576139356142d9565b602002602001015190506000848381518110613953576139536142d9565b60200260200101519050600060c96000848152602001908152602001600020549050818110156139eb5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a206275726e20616d6f756e74206578636565647320746f7460448201527f616c537570706c7900000000000000000000000000000000000000000000000060648201526084016106ae565b600092835260c9602052604090922091039055613a0781614233565b9050613918565b61012d546000906001600160a01b031633148015613a2d575060143610155b15613a5d57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b50335b90565b6067610b668282614409565b6001600160a01b03811681146119d457600080fd5b8035613a8f81613a6f565b919050565b60008060408385031215613aa757600080fd5b8235613ab281613a6f565b946020939093013593505050565b6001600160e01b0319811681146119d457600080fd5b600060208284031215613ae857600080fd5b81356119bc81613ac0565b600060208284031215613b0557600080fd5b5035919050565b60005b83811015613b27578181015183820152602001613b0f565b50506000910152565b60008151808452613b48816020860160208601613b0c565b601f01601f19169290920160200192915050565b6020815260006119bc6020830184613b30565b600080600060608486031215613b8457600080fd5b8335613b8f81613a6f565b95602085013595506040909401359392505050565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff82111715613be057613be0613ba4565b6040525050565b600082601f830112613bf857600080fd5b813567ffffffffffffffff811115613c1257613c12613ba4565b604051613c296020601f19601f8501160182613bba565b818152846020838601011115613c3e57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215613c6d57600080fd5b813567ffffffffffffffff811115613c8457600080fd5b613c9084828501613be7565b949350505050565b600067ffffffffffffffff821115613cb257613cb2613ba4565b5060051b60200190565b600082601f830112613ccd57600080fd5b81356020613cda82613c98565b604051613ce78282613bba565b83815260059390931b8501820192828101915086841115613d0757600080fd5b8286015b84811015613d225780358352918301918301613d0b565b509695505050505050565b600080600060608486031215613d4257600080fd5b8335613d4d81613a6f565b9250602084013567ffffffffffffffff80821115613d6a57600080fd5b613d7687838801613cbc565b93506040860135915080821115613d8c57600080fd5b50613d9986828701613cbc565b9150509250925092565b60008060408385031215613db657600080fd5b50508035926020909101359150565b600080600080600060a08688031215613ddd57600080fd5b8535613de881613a6f565b94506020860135613df881613a6f565b9350604086013567ffffffffffffffff80821115613e1557600080fd5b613e2189838a01613cbc565b94506060880135915080821115613e3757600080fd5b613e4389838a01613cbc565b93506080880135915080821115613e5957600080fd5b50613e6688828901613be7565b9150509295509295909350565b60008060408385031215613e8657600080fd5b823591506020830135613e9881613a6f565b809150509250929050565b60008060408385031215613eb657600080fd5b823567ffffffffffffffff80821115613ece57600080fd5b818501915085601f830112613ee257600080fd5b81356020613eef82613c98565b604051613efc8282613bba565b83815260059390931b8501820192828101915089841115613f1c57600080fd5b948201945b83861015613f43578535613f3481613a6f565b82529482019490820190613f21565b96505086013592505080821115613f5957600080fd5b5061096785828601613cbc565b600081518084526020808501945080840160005b83811015613f9657815187529582019590820190600101613f7a565b509495945050505050565b6020815260006119bc6020830184613f66565b60008060408385031215613fc757600080fd5b82359150602083013567ffffffffffffffff811115613fe557600080fd5b61096785828601613be7565b60006020828403121561400357600080fd5b81356119bc81613a6f565b80151581146119d457600080fd5b6000806040838503121561402f57600080fd5b823561403a81613a6f565b91506020830135613e988161400e565b6000806040838503121561405d57600080fd5b823561406881613a6f565b91506020830135613e9881613a6f565b600080600080600060a0868803121561409057600080fd5b853561409b81613a6f565b945060208601356140ab81613a6f565b93506040860135925060608601359150608086013567ffffffffffffffff8111156140d557600080fd5b613e6688828901613be7565b600080600080600080600060e0888a0312156140fc57600080fd5b67ffffffffffffffff808935111561411357600080fd5b6141208a8a358b01613be7565b9750602089013561413081613a6f565b9650604089013561414081613a6f565b9550606089013561415081613a6f565b9450608089013561416081613a6f565b935060a08901358181111561417457600080fd5b8901601f81018b1361418557600080fd5b803561419081613c98565b60405161419d8282613bba565b80915082815260208101915060208360051b85010192508d8311156141c157600080fd5b602084015b838110156141fa5785813511156141dc57600080fd5b6141ec8f60208335880101613be7565b8352602092830192016141c6565b50809650505050505061420f60c08901613a84565b905092959891949750929550565b634e487b7160e01b600052601160045260246000fd5b600060001982036142465761424661421d565b5060010190565b6000806040838503121561426057600080fd5b825161426b81613a6f565b602084015190925061ffff81168114613e9857600080fd5b80820281158282048414176106dc576106dc61421d565b6000826142b757634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156142ce57600080fd5b81516119bc8161400e565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061430357607f821691505b60208210810361432357634e487b7160e01b600052602260045260246000fd5b50919050565b6000808454614337816142ef565b6001828116801561434f576001811461436457614393565b60ff1984168752821515830287019450614393565b8860005260208060002060005b8581101561438a5781548a820152908401908201614371565b50505082870194505b5050505083516143a7818360208801613b0c565b01949350505050565b808201808211156106dc576106dc61421d565b601f821115610ac957600081815260208120601f850160051c810160208610156143ea5750805b601f850160051c820191505b81811015610a9b578281556001016143f6565b815167ffffffffffffffff81111561442357614423613ba4565b6144378161443184546142ef565b846143c3565b602080601f83116001811461446c57600084156144545750858301515b600019600386901b1c1916600185901b178555610a9b565b600085815260208120601f198616915b8281101561449b5788860151825594840194600190910190840161447c565b50858210156144b95787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6040815260006144dc6040830185613f66565b82810360208401526144ee8185613f66565b95945050505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161452f816017850160208801613b0c565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161456c816028840160208801613b0c565b01602801949350505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526145b060a0830184613b30565b979650505050505050565b6000602082840312156145cd57600080fd5b81516119bc81613ac0565b600060033d1115613a605760046000803e5060005160e01c90565b600060443d10156146015790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff816024840111818411171561464f57505050505090565b82850191508151818111156146675750505050505090565b843d87010160208285010111156146815750505050505090565b61469060208286010187613bba565b509095945050505050565b60006001600160a01b03808816835280871660208401525060a060408301526146c760a0830186613f66565b82810360608401526146d98186613f66565b905082810360808401526146ed8185613b30565b98975050505050505050565b6000816147085761470861421d565b50600019019056fea2646970667358221220984fb4dae22ed4aba9db5e3346aea4e270846b068ed4e6f7516b7ee7d9257fdf64736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "details": "An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to provide a variety of features including, AccessControl, URIStorage, Burnable and more. The contract includes support for meta transactions.", + "events": { + "ApprovalForAll(address,address,bool)": { + "details": "Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to `approved`." + }, + "Initialized(uint8)": { + "details": "Triggered when the contract has been initialized or reinitialized." + }, + "RoleAdminChanged(bytes32,bytes32,bytes32)": { + "details": "Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._" + }, + "RoleGranted(bytes32,address,address)": { + "details": "Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}." + }, + "RoleRevoked(bytes32,address,address)": { + "details": "Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)" + }, + "TransferBatch(address,address,address,uint256[],uint256[])": { + "details": "Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all transfers." + }, + "TransferSingle(address,address,address,uint256,uint256)": { + "details": "Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`." + }, + "TrustedForwarderSet(address,address,address)": { + "params": { + "newTrustedForwarder": "new trusted forwarder", + "oldTrustedForwarder": "old trusted forwarder", + "operator": "the sender of the transaction" + } + }, + "URI(string,uint256)": { + "details": "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}." + } + }, + "kind": "dev", + "methods": { + "addNewCatalystType(string)": { + "params": { + "ipfsCID": "The IPFS content identifiers for the catalyst" + } + }, + "balanceOf(address,uint256)": { + "details": "See {IERC1155-balanceOf}. Requirements: - `account` cannot be the zero address." + }, + "balanceOfBatch(address[],uint256[])": { + "details": "See {IERC1155-balanceOfBatch}. Requirements: - `accounts` and `ids` must have the same length." + }, + "burnBatchFrom(address,uint256[],uint256[])": { + "params": { + "account": "The address to burn from", + "amounts": "The amounts to be burned", + "ids": "The token ids to burn" + } + }, + "burnFrom(address,uint256,uint256)": { + "params": { + "account": "The address to burn from", + "amount": "The amount to be burned", + "id": "The token id to burn" + } + }, + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor" + }, + "exists(uint256)": { + "details": "Indicates whether any token exist with a given id, or not." + }, + "getOperatorFilterRegistry()": { + "returns": { + "operatorFilterRegistryAddress": "address of operator filter registry contract." + } + }, + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getRoyaltyManager()": { + "returns": { + "royaltyManagerAddress": "address of royalty manager contract." + } + }, + "getTrustedForwarder()": { + "returns": { + "_0": "return the address of the trusted forwarder" + } + }, + "grantRole(bytes32,address)": { + "details": "Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event." + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "initialize(string,address,address,address,address,string[],address)": { + "params": { + "_baseUri": "The base URI for the token metadata, most likely set to ipfs://.", + "_catalystIpfsCID": "The IPFS content identifiers for each catalyst.", + "_defaultAdmin": "The default admin address.", + "_defaultMinter": "The default minter address.", + "_royaltyManager": ", the address of the Manager contract for common royalty recipient", + "_subscription": "The subscription address.", + "_trustedForwarder": "The trusted forwarder for meta transactions." + } + }, + "isApprovedForAll(address,address)": { + "details": "See {IERC1155-isApprovedForAll}." + }, + "isTrustedForwarder(address)": { + "params": { + "forwarder": "trusted forwarder address to check" + }, + "returns": { + "_0": "true if the address is the same as the trusted forwarder" + } + }, + "mint(address,uint256,uint256)": { + "params": { + "amount": "The amount to be minted", + "id": "The token id to mint", + "to": "The address that will own the minted token" + } + }, + "mintBatch(address,uint256[],uint256[])": { + "params": { + "amounts": "The amounts to be minted per token id", + "ids": "The token ids to mint", + "to": "The address that will own the minted tokens" + } + }, + "registerAndSubscribe(address,bool)": { + "details": "used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.", + "params": { + "subscribe": "bool to signify subscription \"true\"\" or to copy the list \"false\".", + "subscriptionOrRegistrantToCopy": "registration address of the list to subscribe." + } + }, + "renounceRole(bytes32,address)": { + "details": "Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event." + }, + "revokeRole(bytes32,address)": { + "details": "Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event." + }, + "royaltyInfo(uint256,uint256)": { + "details": "tokenId is one of the EIP2981 args for this function can't be removed", + "params": { + "_salePrice": "the price of token on which the royalty is calculated" + }, + "returns": { + "receiver": "the receiver of royalty", + "royaltyAmount": "the amount of royalty" + } + }, + "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)": { + "details": "call data should be optimized to order ids so packedBalance can be used efficiently.", + "params": { + "data": "additional data accompanying the transfer.", + "from": "address from which tokens are transfered.", + "ids": "ids of each token type transfered.", + "to": "address to which the token will be transfered.", + "values": "amount of each token type transfered." + } + }, + "safeTransferFrom(address,address,uint256,uint256,bytes)": { + "params": { + "data": "additional data accompanying the transfer.", + "from": "address from which tokens are transfered.", + "id": "the token type transfered.", + "to": "address to which the token will be transfered.", + "value": "amount of token transfered." + } + }, + "setApprovalForAll(address,bool)": { + "params": { + "approved": "whether to approve or revoke", + "operator": "address which will be granted rights to transfer all tokens of the caller." + } + }, + "setBaseURI(string)": { + "params": { + "baseURI": "The new base URI" + } + }, + "setMetadataHash(uint256,string)": { + "params": { + "metadataHash": "The new URI", + "tokenId": "The token id to set URI for" + } + }, + "setOperatorRegistry(address)": { + "params": { + "registry": "the address of the registry" + } + }, + "setTrustedForwarder(address)": { + "details": "Change the address of the trusted forwarder for meta-TX", + "params": { + "trustedForwarder": "The new trustedForwarder" + } + }, + "supportsInterface(bytes4)": { + "params": { + "interfaceId": "the interface identifier, as specified in ERC-165." + }, + "returns": { + "_0": "`true` if the contract implements `interfaceId`." + } + }, + "totalSupply(uint256)": { + "details": "Total amount of tokens in with a given id." + }, + "uri(uint256)": { + "params": { + "tokenId": "The token id to get URI for" + }, + "returns": { + "_0": "tokenURI the URI of the token" + } + } + }, + "title": "Catalyst", + "version": 1 + }, + "userdoc": { + "events": { + "TrustedForwarderSet(address,address,address)": { + "notice": "Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`" + } + }, + "kind": "user", + "methods": { + "addNewCatalystType(string)": { + "notice": "Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only" + }, + "burnBatchFrom(address,uint256[],uint256[])": { + "notice": "Burns a batch of tokens from a specific address" + }, + "burnFrom(address,uint256,uint256)": { + "notice": "Burns a specified amount of tokens from a specific address" + }, + "getOperatorFilterRegistry()": { + "notice": "returns the operator filter registry." + }, + "getRoyaltyManager()": { + "notice": "returns the royalty manager" + }, + "getTrustedForwarder()": { + "notice": "return the address of the trusted forwarder" + }, + "initialize(string,address,address,address,address,string[],address)": { + "notice": "Initialize the contract, setting up initial values for various features." + }, + "isTrustedForwarder(address)": { + "notice": "return true if the forwarder is the trusted forwarder" + }, + "mint(address,uint256,uint256)": { + "notice": "Mints a new token, limited to MINTER_ROLE only" + }, + "mintBatch(address,uint256[],uint256[])": { + "notice": "Mints a batch of tokens, limited to MINTER_ROLE only" + }, + "registerAndSubscribe(address,bool)": { + "notice": "This function is used to register Catalyst contract on the Operator Filterer Registry of OpenSea. Can only be called by admin." + }, + "royaltyInfo(uint256,uint256)": { + "notice": "Returns how much royalty is owed and to whom based on ERC2981" + }, + "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)": { + "notice": "Transfers `values` tokens of type `ids` from `from` to `to` (with safety call)." + }, + "safeTransferFrom(address,address,uint256,uint256,bytes)": { + "notice": "Transfers `value` tokens of type `id` from `from` to `to` (with safety call)." + }, + "setApprovalForAll(address,bool)": { + "notice": "Enable or disable approval for `operator` to manage all of the caller's tokens." + }, + "setBaseURI(string)": { + "notice": "Set a new base URI" + }, + "setMetadataHash(uint256,string)": { + "notice": "Set a new URI for specific tokenid" + }, + "setOperatorRegistry(address)": { + "notice": "sets filter registry address" + }, + "setTrustedForwarder(address)": { + "notice": "Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only" + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements interface `id`." + }, + "uri(uint256)": { + "notice": "returns full token URI, including baseURI and token metadata URI" + } + }, + "notice": "This contract manages catalysts which are used to mint new assets.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 502, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 505, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 2965, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 3888, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 820, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_balances", + "offset": 0, + "slot": "101", + "type": "t_mapping(t_uint256,t_mapping(t_address,t_uint256))" + }, + { + "astId": 826, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_operatorApprovals", + "offset": 0, + "slot": "102", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + }, + { + "astId": 828, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_uri", + "offset": 0, + "slot": "103", + "type": "t_string_storage" + }, + { + "astId": 2035, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "104", + "type": "t_array(t_uint256)47_storage" + }, + { + "astId": 2287, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "151", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 2313, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_totalSupply", + "offset": 0, + "slot": "201", + "type": "t_mapping(t_uint256,t_uint256)" + }, + { + "astId": 2464, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "202", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 2499, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_baseURI", + "offset": 0, + "slot": "251", + "type": "t_string_storage" + }, + { + "astId": 2503, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_tokenURIs", + "offset": 0, + "slot": "252", + "type": "t_mapping(t_uint256,t_string_storage)" + }, + { + "astId": 2578, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "253", + "type": "t_array(t_uint256)48_storage" + }, + { + "astId": 11744, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_trustedForwarder", + "offset": 0, + "slot": "301", + "type": "t_address" + }, + { + "astId": 11855, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "302", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 82, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "_roles", + "offset": 0, + "slot": "351", + "type": "t_mapping(t_bytes32,t_struct(RoleData)77_storage)" + }, + { + "astId": 377, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "352", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 11876, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "operatorFilterRegistry", + "offset": 0, + "slot": "401", + "type": "t_contract(IOperatorFilterRegistry)12300" + }, + { + "astId": 12080, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "402", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 12751, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "royaltyManager", + "offset": 0, + "slot": "451", + "type": "t_contract(IRoyaltyManager)13053" + }, + { + "astId": 12859, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "452", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 9845, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "highestTierIndex", + "offset": 0, + "slot": "501", + "type": "t_uint256" + }, + { + "astId": 10527, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "__gap", + "offset": 0, + "slot": "502", + "type": "t_array(t_uint256)49_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)47_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[47]", + "numberOfBytes": "1504" + }, + "t_array(t_uint256)48_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[48]", + "numberOfBytes": "1536" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IOperatorFilterRegistry)12300": { + "encoding": "inplace", + "label": "contract IOperatorFilterRegistry", + "numberOfBytes": "20" + }, + "t_contract(IRoyaltyManager)13053": { + "encoding": "inplace", + "label": "contract IRoyaltyManager", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_struct(RoleData)77_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)77_storage" + }, + "t_mapping(t_uint256,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_uint256,t_string_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => string)", + "numberOfBytes": "32", + "value": "t_string_storage" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(RoleData)77_storage": { + "encoding": "inplace", + "label": "struct AccessControlUpgradeable.RoleData", + "members": [ + { + "astId": 74, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 76, + "contract": "@sandbox-smart-contracts/asset/contracts/Catalyst.sol:Catalyst", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/Catalyst_Proxy.json b/packages/deploy/deployments/mumbai/Catalyst_Proxy.json new file mode 100644 index 0000000000..1a45ee8671 --- /dev/null +++ b/packages/deploy/deployments/mumbai/Catalyst_Proxy.json @@ -0,0 +1,452 @@ +{ + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x059C6c226ec83742932B259153f63e333B767A50", + "transactionIndex": 7, + "gasUsed": "1562454", + "logsBloom": "0x04000004000000000000008000000000400000000800000000000090100000000002000000008420000000000001004000208100020400000000000000040000000090040004010000000020000002800010000000040000000100000000000008000004020000000000020000000801000000800000000080000000001000000000010440000210000020000000001000000800100081042000000000a00000200000000000000000000100000400000000000000800000003000080400404000000020004000000001000000040200001000008400000100108000001060002000090000000000000000200000000804000000088000001002000000100000", + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58", + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000000675d3ad952e443635ad76a22dceab391556a0d3" + ], + "data": "0x", + "logIndex": 37, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x8ca022029d8ff7ad974913f8970aeed6c5e0e7eaf494a0c5b262249f6b5759e5", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 38, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59", + "0x000000000000000000000000059c6c226ec83742932b259153f63e333b767a50", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 39, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x0038c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8", + "0x000000000000000000000000059c6c226ec83742932b259153f63e333b767a50", + "0x0000000000000000000000004bd0ad9d60d686a259fbcd8c56ce6100d7031e35", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 40, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0xf9c7803e94e0d3c02900d8a90893a6d5e90dd04d32a4cfe825520f82bf9f32f6" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000", + "logIndex": 41, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 42, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 43, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x1ad03d64d67ed9b2c90cfdf8dc8e54de3e41af88ae55e45a53dc27e476406de8", + "0x000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da21" + ], + "data": "0x", + "logIndex": 44, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261667962656965636e7a37736e7837363374637877627369746275636c74637870376d6135736971626764613335626c3374736665657469346d000000000000000000000000000000000000000000000000000000000000", + "logIndex": 45, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696235746b793364677363377a793633376466756e62347a77776e707a6f33773369357465706266656534326571337372776e7771000000000000000000000000000000000000000000000000000000000000", + "logIndex": 46, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000002" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696567657676696d357133617469346874736e63787773656a6663336c626b7a6237776e326132667a7468633674736f663776376d000000000000000000000000000000000000000000000000000000000000", + "logIndex": 47, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000003" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696668746b6f75356133327872746b746476667172766768346d70326f68766c79716473696835786b346b67636679777478656669000000000000000000000000000000000000000000000000000000000000", + "logIndex": 48, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000004" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b7265696771706237716f3369716b61343234336f6168336e6b6136616778336e6d76777a6175787a65326a7a6e6f7478337a776f7a7165000000000000000000000000000000000000000000000000000000000000", + "logIndex": 49, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000005" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569683369747369776b6e3275727a66766732366d627933737367667368766472367a6661627236727878726c7a68656471696c3465000000000000000000000000000000000000000000000000000000000000", + "logIndex": 50, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b", + "0x0000000000000000000000000000000000000000000000000000000000000006" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569626d6e6761756f7a7a69647a3265657679796233756d66326577377a6578696e673367687570366c37696f32616f3532326d7679000000000000000000000000000000000000000000000000000000000000", + "logIndex": 51, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 52, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x059C6c226ec83742932B259153f63e333B767A50", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 53, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + }, + { + "transactionIndex": 7, + "blockNumber": 40238265, + "transactionHash": "0x3b558538d3d65d9599c6a544ab8adf972818af65fb639eda58453a2a8fe58e53", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000f903ba9e006193c1527bfbe65fe2123704ea3f99" + ], + "data": "0x00000000000000000000000000000000000000000000000000085390c178ca0000000000000000000000000000000000000000000000000fbfeef789dc0bb1d4000000000000000000000000000000000000000000001142a6bda6715ef2d99f00000000000000000000000000000000000000000000000fbfe6a3f91a92e7d4000000000000000000000000000000000000000000001142a6c5fa02206ba39f", + "logIndex": 54, + "blockHash": "0xded2567bf13ef29414aa49fa195f092fe15a5cbf65f135d746bb02fd52d22e58" + } + ], + "blockNumber": 40238265, + "cumulativeGasUsed": "2378638", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0675d3Ad952e443635AD76A22Dceab391556A0d3", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0xf3bdecc100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f70000000000000000000000004bd0ad9d60d686a259fbcd8c56ce6100d7031e3500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc6121811650000000000000000000000000000000000000000000000000000000000000120000000000000000000000000c7a0bfc1df5c9ca04ef63c1ea2f18af2fbf6da210000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000003b6261667962656965636e7a37736e7837363374637877627369746275636c74637870376d6135736971626764613335626c3374736665657469346d0000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696235746b793364677363377a793633376466756e62347a77776e707a6f33773369357465706266656534326571337372776e77710000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696567657676696d357133617469346874736e63787773656a6663336c626b7a6237776e326132667a7468633674736f663776376d0000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696668746b6f75356133327872746b746476667172766768346d70326f68766c79716473696835786b346b676366797774786566690000000000000000000000000000000000000000000000000000000000000000000000003b6261666b7265696771706237716f3369716b61343234336f6168336e6b6136616778336e6d76777a6175787a65326a7a6e6f7478337a776f7a71650000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569683369747369776b6e3275727a66766732366d627933737367667368766472367a6661627236727878726c7a68656471696c34650000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569626d6e6761756f7a7a69647a3265657679796233756d66326577377a6578696e673367687570366c37696f32616f3532326d76790000000000" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/DEFAULT_SUBSCRIPTION.json b/packages/deploy/deployments/mumbai/DEFAULT_SUBSCRIPTION.json new file mode 100644 index 0000000000..fce80b9790 --- /dev/null +++ b/packages/deploy/deployments/mumbai/DEFAULT_SUBSCRIPTION.json @@ -0,0 +1,87 @@ +{ + "address": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/packages/deploy/deployments/mumbai/DefaultProxyAdmin.json b/packages/deploy/deployments/mumbai/DefaultProxyAdmin.json index 6b5bf33406..e916f85993 100644 --- a/packages/deploy/deployments/mumbai/DefaultProxyAdmin.json +++ b/packages/deploy/deployments/mumbai/DefaultProxyAdmin.json @@ -1,11 +1,11 @@ { - "address": "0xD20fbd836e80DabFb777E6AaBbe52e96c07eCD1B", + "address": "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", "abi": [ { "inputs": [ { "internalType": "address", - "name": "owner", + "name": "initialOwner", "type": "address" } ], @@ -162,57 +162,60 @@ "type": "function" } ], - "transactionHash": "0xb2106351159af7d3694430eddea9b028cc13b4d4c9085be8fa283bdc6cee939e", + "transactionHash": "0x10c9be2550bdeb7301aa33f7fb27ed64ba0753e7e78c042f0c38aa19a9eeef21", "receipt": { "to": null, "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", - "contractAddress": "0xD20fbd836e80DabFb777E6AaBbe52e96c07eCD1B", - "transactionIndex": 0, - "gasUsed": "671461", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000002000000008400000000000000000000008000000000000000010000000000000000000000000000000000010000800001000000000000000100000000004000000000020000000000020000000800000000000000000080000000000000400000000000000000000000000000000000000000000080000000000000200000200000000000000000000000000800000000000000000000000000000000004000000000000000000001000000000000000000000000000000108040000020000000000000000000000000000000000000000000000000000000000000100000", - "blockHash": "0xf5d7e81d060f51731ea3bbf06e52707c00fd9fc45d31d6fd69caa3e77cba2bf2", - "transactionHash": "0xb2106351159af7d3694430eddea9b028cc13b4d4c9085be8fa283bdc6cee939e", + "contractAddress": "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "transactionIndex": 11, + "gasUsed": "643983", + "logsBloom": "0x00008000000000000000000000000000000000000000000000800010000000000002000000008420000000000000000000008000000000800000000000000000000000000000000000000000000000800001000000000000000100000000000000000000020000000000020000000800000000000000000080000000000000400000000000000000000000000000000000000000000000000000000000200000200000000000000000000000000000000000000004000000000000000000004000000000000000000001000000000000000000000000000000108000001020000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x454d8c7929129817b489142ed4701498c50345a5339ec131ffdb0b6b33db5e15", + "transactionHash": "0x10c9be2550bdeb7301aa33f7fb27ed64ba0753e7e78c042f0c38aa19a9eeef21", "logs": [ { - "transactionIndex": 0, - "blockNumber": 18714258, - "transactionHash": "0xb2106351159af7d3694430eddea9b028cc13b4d4c9085be8fa283bdc6cee939e", - "address": "0xD20fbd836e80DabFb777E6AaBbe52e96c07eCD1B", + "transactionIndex": 11, + "blockNumber": 40238236, + "transactionHash": "0x10c9be2550bdeb7301aa33f7fb27ed64ba0753e7e78c042f0c38aa19a9eeef21", + "address": "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165" ], "data": "0x", - "logIndex": 0, - "blockHash": "0xf5d7e81d060f51731ea3bbf06e52707c00fd9fc45d31d6fd69caa3e77cba2bf2" + "logIndex": 53, + "blockHash": "0x454d8c7929129817b489142ed4701498c50345a5339ec131ffdb0b6b33db5e15" }, { - "transactionIndex": 0, - "blockNumber": 18714258, - "transactionHash": "0xb2106351159af7d3694430eddea9b028cc13b4d4c9085be8fa283bdc6cee939e", + "transactionIndex": 11, + "blockNumber": 40238236, + "transactionHash": "0x10c9be2550bdeb7301aa33f7fb27ed64ba0753e7e78c042f0c38aa19a9eeef21", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", - "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + "0x000000000000000000000000f903ba9e006193c1527bfbe65fe2123704ea3f99" ], - "data": "0x000000000000000000000000000000000000000000000000001315859315900000000000000000000000000000000000000000000000000001d6781bd5c648000000000000000000000000000000000000000000000000b5549ad6ab6053dce800000000000000000000000000000000000000000000000001c3629642b0b8000000000000000000000000000000000000000000000000b554adec30f3696ce8", - "logIndex": 1, - "blockHash": "0xf5d7e81d060f51731ea3bbf06e52707c00fd9fc45d31d6fd69caa3e77cba2bf2" + "data": "0x00000000000000000000000000000000000000000000000000059af67d438be300000000000000000000000000000000000000000000000fc059e547b278a51e000000000000000000000000000000000000000000001142a4bac4f1fbbe255a00000000000000000000000000000000000000000000000fc0544a513535193b000000000000000000000000000000000000000000001142a4c05fe87901b13d", + "logIndex": 54, + "blockHash": "0x454d8c7929129817b489142ed4701498c50345a5339ec131ffdb0b6b33db5e15" } ], - "blockNumber": 18714258, - "cumulativeGasUsed": "671461", + "blockNumber": 40238236, + "cumulativeGasUsed": "2141957", "status": 1, "byzantium": true }, - "args": ["0x49c4D4C94829B9c44052C5f5Cb164Fc612181165"], - "solcInputHash": "1635d55d57a0a2552952c0d22586ed23", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.7/openzeppelin/proxy/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.7/openzeppelin/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x910a2e625b71168563edf9eeef55a50d6d699acfe27ceba3921f291829a8f938\",\"license\":\"MIT\"},\"solc_0.7/openzeppelin/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 (address initialOwner) {\\n _owner = initialOwner;\\n emit OwnershipTransferred(address(0), initialOwner);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(_owner == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x85eb3b8575f16937ed27e36fae8b617d9e3e7a7e49f04e10d52dad66d0fa9e75\",\"license\":\"MIT\"},\"solc_0.7/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n * \\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n * \\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n * \\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal {\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 { revert(0, returndatasize()) }\\n default { return(0, returndatasize()) }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal virtual view returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n * \\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback () payable external {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive () payable external {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n * \\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {\\n }\\n}\\n\",\"keccak256\":\"0xc33f9858a67e34c77831163d5611d21fc627dfd2c303806a98a6c9db5a01b034\",\"license\":\"MIT\"},\"solc_0.7/openzeppelin/proxy/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../access/Ownable.sol\\\";\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n constructor(address owner) Ownable(owner) {}\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0xae77885dd899a14e94f172e4e9ec7ef4b2ced0472904626c59b46150a26b5714\",\"license\":\"MIT\"},\"solc_0.7/openzeppelin/proxy/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./UpgradeableProxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n * \\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n * \\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n * \\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n * \\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative inerface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is UpgradeableProxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.\\n */\\n constructor(address initialLogic, address initialAdmin, bytes memory _data) payable UpgradeableProxy(initialLogic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _setAdmin(initialAdmin);\\n }\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _admin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n * \\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n * \\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address) {\\n return _admin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n * \\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n * \\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address) {\\n return _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n * \\n * Emits an {AdminChanged} event.\\n * \\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external ifAdmin {\\n require(newAdmin != address(0), \\\"TransparentUpgradeableProxy: new admin is the zero address\\\");\\n emit AdminChanged(_admin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n * \\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeTo(newImplementation);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n * \\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeTo(newImplementation);\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success,) = newImplementation.delegatecall(data);\\n require(success);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view returns (address adm) {\\n bytes32 slot = _ADMIN_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n adm := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n bytes32 slot = _ADMIN_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newAdmin)\\n }\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal override virtual {\\n require(msg.sender != _admin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0xd6cecbe00dc78355aff1a16d83487bb73c54701004d61a2e48cdb81e2bcacc26\",\"license\":\"MIT\"},\"solc_0.7/openzeppelin/proxy/UpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./Proxy.sol\\\";\\nimport \\\"../utils/Address.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n * \\n * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see\\n * {TransparentUpgradeableProxy}.\\n */\\ncontract UpgradeableProxy is Proxy {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n * \\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _setImplementation(_logic);\\n if(_data.length > 0) {\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success,) = _logic.delegatecall(_data);\\n require(success);\\n }\\n }\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal override view returns (address impl) {\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n impl := sload(slot)\\n }\\n }\\n\\n /**\\n * @dev Upgrades the proxy to a new implementation.\\n * \\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"UpgradeableProxy: new implementation is not a contract\\\");\\n\\n bytes32 slot = _IMPLEMENTATION_SLOT;\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sstore(slot, newImplementation)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd68f4c11941712db79a61b9dca81a5db663cfacec3d7bb19f8d2c23bb1ab8afe\",\"license\":\"MIT\"},\"solc_0.7/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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 functionCall(target, data, \\\"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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\n if (success) {\\n return returndata;\\n } else {\\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\\n // solhint-disable-next-line no-inline-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\",\"keccak256\":\"0x698f929f1097637d051976b322a2d532c27df022b09010e8d091e2888a5ebdf8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50604051610b54380380610b548339818101604052602081101561003357600080fd5b5051600080546001600160a01b0319166001600160a01b03831690811782556040518392907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35050610ac68061008e6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461015d57806399a88ec414610229578063f2fde38b14610271578063f3b7dead146102b15761007b565b8063204e1c7a14610080578063715018a6146100e95780637eff275e146101005780638da5cb5b14610148575b600080fd5b34801561008c57600080fd5b506100c0600480360360208110156100a357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166102f1565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156100f557600080fd5b506100fe6103a9565b005b34801561010c57600080fd5b506100fe6004803603604081101561012357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166104a9565b34801561015457600080fd5b506100c06105bf565b6100fe6004803603606081101561017357600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135909116918101906060810160408201356401000000008111156101b457600080fd5b8201836020820111156101c657600080fd5b803590602001918460018302840111640100000000831117156101e857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506105db945050505050565b34801561023557600080fd5b506100fe6004803603604081101561024c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661075d565b34801561027d57600080fd5b506100fe6004803603602081101561029457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610857565b3480156102bd57600080fd5b506100c0600480360360208110156102d457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166109e1565b60008060008373ffffffffffffffffffffffffffffffffffffffff1660405180807f5c60da1b000000000000000000000000000000000000000000000000000000008152506004019050600060405180830381855afa9150503d8060008114610376576040519150601f19603f3d011682016040523d82523d6000602084013e61037b565b606091505b50915091508161038a57600080fd5b80806020019051602081101561039f57600080fd5b5051949350505050565b6103b1610a66565b60005473ffffffffffffffffffffffffffffffffffffffff90811691161461043a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6104b1610a66565b60005473ffffffffffffffffffffffffffffffffffffffff90811691161461053a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8173ffffffffffffffffffffffffffffffffffffffff16638f283970826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156105a357600080fd5b505af11580156105b7573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6105e3610a66565b60005473ffffffffffffffffffffffffffffffffffffffff90811691161461066c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8273ffffffffffffffffffffffffffffffffffffffff16634f1ef2863484846040518463ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156106f35781810151838201526020016106db565b50505050905090810190601f1680156107205780820380516001836020036101000a031916815260200191505b5093505050506000604051808303818588803b15801561073f57600080fd5b505af1158015610753573d6000803e3d6000fd5b5050505050505050565b610765610a66565b60005473ffffffffffffffffffffffffffffffffffffffff9081169116146107ee57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8173ffffffffffffffffffffffffffffffffffffffff16633659cfe6826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156105a357600080fd5b61085f610a66565b60005473ffffffffffffffffffffffffffffffffffffffff9081169116146108e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610954576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a6b6026913960400191505060405180910390fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008060008373ffffffffffffffffffffffffffffffffffffffff1660405180807ff851a440000000000000000000000000000000000000000000000000000000008152506004019050600060405180830381855afa9150503d8060008114610376576040519150601f19603f3d011682016040523d82523d6000602084013e61037b565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a264697066735822122033c7eab8e5a7904ed291c191ebc004b4929d46e0bcbd0fea73fa80b0475d931164736f6c63430007060033", - "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461015d57806399a88ec414610229578063f2fde38b14610271578063f3b7dead146102b15761007b565b8063204e1c7a14610080578063715018a6146100e95780637eff275e146101005780638da5cb5b14610148575b600080fd5b34801561008c57600080fd5b506100c0600480360360208110156100a357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166102f1565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b3480156100f557600080fd5b506100fe6103a9565b005b34801561010c57600080fd5b506100fe6004803603604081101561012357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166104a9565b34801561015457600080fd5b506100c06105bf565b6100fe6004803603606081101561017357600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135909116918101906060810160408201356401000000008111156101b457600080fd5b8201836020820111156101c657600080fd5b803590602001918460018302840111640100000000831117156101e857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506105db945050505050565b34801561023557600080fd5b506100fe6004803603604081101561024c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661075d565b34801561027d57600080fd5b506100fe6004803603602081101561029457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610857565b3480156102bd57600080fd5b506100c0600480360360208110156102d457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166109e1565b60008060008373ffffffffffffffffffffffffffffffffffffffff1660405180807f5c60da1b000000000000000000000000000000000000000000000000000000008152506004019050600060405180830381855afa9150503d8060008114610376576040519150601f19603f3d011682016040523d82523d6000602084013e61037b565b606091505b50915091508161038a57600080fd5b80806020019051602081101561039f57600080fd5b5051949350505050565b6103b1610a66565b60005473ffffffffffffffffffffffffffffffffffffffff90811691161461043a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6104b1610a66565b60005473ffffffffffffffffffffffffffffffffffffffff90811691161461053a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8173ffffffffffffffffffffffffffffffffffffffff16638f283970826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156105a357600080fd5b505af11580156105b7573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6105e3610a66565b60005473ffffffffffffffffffffffffffffffffffffffff90811691161461066c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8273ffffffffffffffffffffffffffffffffffffffff16634f1ef2863484846040518463ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156106f35781810151838201526020016106db565b50505050905090810190601f1680156107205780820380516001836020036101000a031916815260200191505b5093505050506000604051808303818588803b15801561073f57600080fd5b505af1158015610753573d6000803e3d6000fd5b5050505050505050565b610765610a66565b60005473ffffffffffffffffffffffffffffffffffffffff9081169116146107ee57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8173ffffffffffffffffffffffffffffffffffffffff16633659cfe6826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156105a357600080fd5b61085f610a66565b60005473ffffffffffffffffffffffffffffffffffffffff9081169116146108e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610954576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610a6b6026913960400191505060405180910390fd5b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008060008373ffffffffffffffffffffffffffffffffffffffff1660405180807ff851a440000000000000000000000000000000000000000000000000000000008152506004019050600060405180830381855afa9150503d8060008114610376576040519150601f19603f3d011682016040523d82523d6000602084013e61037b565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373a264697066735822122033c7eab8e5a7904ed291c191ebc004b4929d46e0bcbd0fea73fa80b0475d931164736f6c63430007060033", + "args": [ + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (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 (address initialOwner) {\\n _transferOwnership(initialOwner);\\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 called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing 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\",\"keccak256\":\"0x9b2bbba5bb04f53f277739c1cdff896ba8b3bf591cfc4eab2098c655e8ac251e\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\nimport \\\"../../access/Ownable.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n constructor (address initialOwner) Ownable(initialOwner) {}\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(\\n TransparentUpgradeableProxy proxy,\\n address implementation,\\n bytes memory data\\n ) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x754888b9c9ab5525343460b0a4fa2e2f4fca9b6a7e0e7ddea4154e2b1182a45d\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610b17380380610b1783398101604081905261002f91610090565b8061003981610040565b50506100c0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100a257600080fd5b81516001600160a01b03811681146100b957600080fd5b9392505050565b610a48806100cf6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", "devdoc": { "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.", "kind": "dev", @@ -252,8 +255,8 @@ "storageLayout": { "storage": [ { - "astId": 30, - "contract": "solc_0.7/openzeppelin/proxy/ProxyAdmin.sol:ProxyAdmin", + "astId": 7, + "contract": "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", "label": "_owner", "offset": 0, "slot": "0", @@ -268,4 +271,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/OPERATOR_FILTER_REGISTRY.json b/packages/deploy/deployments/mumbai/OPERATOR_FILTER_REGISTRY.json new file mode 100644 index 0000000000..06f9fe066b --- /dev/null +++ b/packages/deploy/deployments/mumbai/OPERATOR_FILTER_REGISTRY.json @@ -0,0 +1,498 @@ +{ + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "AddressAlreadyFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "filtered", "type": "address" } + ], + "name": "AddressFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "AddressNotFiltered", + "type": "error" + }, + { "inputs": [], "name": "AlreadyRegistered", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "name": "AlreadySubscribed", + "type": "error" + }, + { "inputs": [], "name": "CannotCopyFromSelf", "type": "error" }, + { "inputs": [], "name": "CannotFilterEOAs", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "CannotSubscribeToRegistrantWithSubscription", + "type": "error" + }, + { "inputs": [], "name": "CannotSubscribeToSelf", "type": "error" }, + { "inputs": [], "name": "CannotSubscribeToZeroAddress", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "name": "CannotUpdateWhileSubscribed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "CodeHashAlreadyFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "CodeHashFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "CodeHashNotFiltered", + "type": "error" + }, + { "inputs": [], "name": "NotOwnable", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "NotRegistered", + "type": "error" + }, + { "inputs": [], "name": "NotSubscribed", "type": "error" }, + { "inputs": [], "name": "OnlyAddressOrOwner", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "codeHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "CodeHashUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "codeHashes", + "type": "bytes32[]" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "CodeHashesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "OperatorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "operators", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "OperatorsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "registered", + "type": "bool" + } + ], + "name": "RegistrationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "subscription", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "subscribed", + "type": "bool" + } + ], + "name": "SubscriptionUpdated", + "type": "event" + }, + { + "inputs": [{ "internalType": "address", "name": "a", "type": "address" }], + "name": "codeHashOf", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "registrantToCopy", + "type": "address" + } + ], + "name": "copyEntriesOf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "filteredCodeHashAt", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "filteredCodeHashes", + "outputs": [ + { "internalType": "bytes32[]", "name": "", "type": "bytes32[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "filteredOperatorAt", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "filteredOperators", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "isCodeHashFiltered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "operatorWithCode", + "type": "address" + } + ], + "name": "isCodeHashOfFiltered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "isOperatorAllowed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "isOperatorFiltered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "isRegistered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "register", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "registrantToCopy", + "type": "address" + } + ], + "name": "registerAndCopyEntries", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "name": "registerAndSubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "newSubscription", + "type": "address" + } + ], + "name": "subscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "subscriberAt", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "subscribers", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "subscriptionOf", + "outputs": [ + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "unregister", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "bool", + "name": "copyExistingEntries", + "type": "bool" + } + ], + "name": "unsubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateCodeHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "bytes32[]", + "name": "codeHashes", + "type": "bytes32[]" + }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateCodeHashes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address[]", + "name": "operators", + "type": "address[]" + }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateOperators", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/packages/deploy/deployments/mumbai/OperatorFilterSubscription.json b/packages/deploy/deployments/mumbai/OperatorFilterSubscription.json new file mode 100644 index 0000000000..2d9be99c02 --- /dev/null +++ b/packages/deploy/deployments/mumbai/OperatorFilterSubscription.json @@ -0,0 +1,196 @@ +{ + "address": "0x4bd0ad9D60d686a259fBCD8C56CE6100D7031e35", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_SUBSCRIPTION", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPERATOR_FILTER_REGISTRY", + "outputs": [ + { + "internalType": "contract IOperatorFilterRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x84ddb0de199bf5230bf8e0b29a2c3177b0bc3d80633162e78067482604b50bcc", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x4bd0ad9D60d686a259fBCD8C56CE6100D7031e35", + "transactionIndex": 2, + "gasUsed": "291868", + "logsBloom": "0x00000000000000000000000000000000000000000800000000800010100000000002000000000020000000000000000000008000000000000000000000040000000080000004000000000000000000800001000000040000000100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000200000000000000000000000000000000000000000000200000200000000000000000000000000000000000000400000000000000000000004002000000004000000001000000000200000000000000000000108000001060004000090000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x37d6e43549c82a898eca9d08015fe0b8645ac28d2c471d3f2838ea59536ba5ca", + "transactionHash": "0x84ddb0de199bf5230bf8e0b29a2c3177b0bc3d80633162e78067482604b50bcc", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 40238259, + "transactionHash": "0x84ddb0de199bf5230bf8e0b29a2c3177b0bc3d80633162e78067482604b50bcc", + "address": "0x4bd0ad9D60d686a259fBCD8C56CE6100D7031e35", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 13, + "blockHash": "0x37d6e43549c82a898eca9d08015fe0b8645ac28d2c471d3f2838ea59536ba5ca" + }, + { + "transactionIndex": 2, + "blockNumber": 40238259, + "transactionHash": "0x84ddb0de199bf5230bf8e0b29a2c3177b0bc3d80633162e78067482604b50bcc", + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "topics": [ + "0x86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59", + "0x0000000000000000000000004bd0ad9d60d686a259fbcd8c56ce6100d7031e35", + "0x0000000000000000000000000000000000000000000000000000000000000001" + ], + "data": "0x", + "logIndex": 14, + "blockHash": "0x37d6e43549c82a898eca9d08015fe0b8645ac28d2c471d3f2838ea59536ba5ca" + }, + { + "transactionIndex": 2, + "blockNumber": 40238259, + "transactionHash": "0x84ddb0de199bf5230bf8e0b29a2c3177b0bc3d80633162e78067482604b50bcc", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000f903ba9e006193c1527bfbe65fe2123704ea3f99" + ], + "data": "0x00000000000000000000000000000000000000000000000000028a5bbe664fec00000000000000000000000000000000000000000000000fc01463db8381fc2e000000000000000000000000000000000000000000001142a59c6f67508c9f2900000000000000000000000000000000000000000000000fc011d97fc51bac42000000000000000000000000000000000000000000001142a59ef9c30ef2ef15", + "logIndex": 15, + "blockHash": "0x37d6e43549c82a898eca9d08015fe0b8645ac28d2c471d3f2838ea59536ba5ca" + } + ], + "blockNumber": 40238259, + "cumulativeGasUsed": "686463", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "af7236032b56a5cadc46f21dd0482b3b", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_SUBSCRIPTION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OPERATOR_FILTER_REGISTRY\",\"outputs\":[{\"internalType\":\"contract IOperatorFilterRegistry\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"OperatorFilterSubription\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on OpenSea operator filter registry\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFilterSubscription.sol\":\"OperatorFilterSubscription\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"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\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFilterSubscription.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IOperatorFilterRegistry} from \\\"./interfaces/IOperatorFilterRegistry.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/// @title OperatorFilterSubription\\n/// @author The Sandbox\\n/// @notice This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on OpenSea operator filter registry\\ncontract OperatorFilterSubscription is Ownable {\\n address public constant DEFAULT_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;\\n\\n // solhint-disable-next-line const-name-snakecase\\n IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =\\n IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);\\n\\n constructor() Ownable() {\\n // Subscribe and copy the entries of the Default subscription list of OpenSea.\\n if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {\\n OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbf0da3d6934bdcfddaa844963f56cf2e3def753244bddf15275d8021ae8a2670\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @title IOperatorFilterRegistry\\n/// @notice Interface for managing operators and filtering.\\ninterface IOperatorFilterRegistry {\\n ///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\\n /// true if supplied registrant address is not registered.\\n function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed);\\n\\n ///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\\n function register(address registrant) external;\\n\\n ///@notice Registers an address with the registry and \\\"subscribes\\\" to another address's filtered operators and codeHashes.\\n function registerAndSubscribe(address registrant, address subscription) external;\\n\\n ///@notice Registers an address with the registry and copies the filtered operators and codeHashes from another\\n /// address without subscribing.\\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\\n\\n ///@notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\\n /// Note that this does not remove any filtered addresses or codeHashes.\\n /// Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\\n function unregister(address addr) external;\\n\\n ///@notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\\n function updateOperator(\\n address registrant,\\n address operator,\\n bool filtered\\n ) external;\\n\\n ///@notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\\n function updateOperators(\\n address registrant,\\n address[] calldata operators,\\n bool filtered\\n ) external;\\n\\n ///@notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\\n function updateCodeHash(\\n address registrant,\\n bytes32 codehash,\\n bool filtered\\n ) external;\\n\\n ///@notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\\n function updateCodeHashes(\\n address registrant,\\n bytes32[] calldata codeHashes,\\n bool filtered\\n ) external;\\n\\n ///@notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\\n /// subscription if present.\\n /// Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\\n /// subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\\n /// used.\\n function subscribe(address registrant, address registrantToSubscribe) external;\\n\\n ///@notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\\n function unsubscribe(address registrant, bool copyExistingEntries) external;\\n\\n ///@notice Get the subscription address of a given registrant, if any.\\n function subscriptionOf(address addr) external returns (address registrant);\\n\\n ///@notice Get the set of addresses subscribed to a given registrant.\\n /// Note that order is not guaranteed as updates are made.\\n function subscribers(address registrant) external returns (address[] memory subscribersList);\\n\\n ///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\\n /// Note that order is not guaranteed as updates are made.\\n function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress);\\n\\n ///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\\n function copyEntriesOf(address registrant, address registrantToCopy) external;\\n\\n ///@notice Returns true if operator is filtered by a given address or its subscription.\\n function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered);\\n\\n ///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered);\\n\\n ///@notice Returns true if a codeHash is filtered by a given address or its subscription.\\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered);\\n\\n ///@notice Returns a list of filtered operators for a given address or its subscription.\\n function filteredOperators(address addr) external returns (address[] memory operatorList);\\n\\n ///@notice Returns the set of filtered codeHashes for a given address or its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList);\\n\\n ///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\\n /// its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredOperatorAt(address registrant, uint256 index) external returns (address operator);\\n\\n ///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\\n /// its subscription.\\n /// Note that order is not guaranteed as updates are made.\\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash);\\n\\n ///@notice Returns true if an address has registered\\n function isRegistered(address addr) external returns (bool registered);\\n\\n ///@dev Convenience method to compute the code hash of an arbitrary contract\\n function codeHashOf(address addr) external returns (bytes32 codeHash);\\n}\\n\",\"keccak256\":\"0x3954f1465330c8645891a1d566723f9804515632be2025edd02b00a0e53d2f30\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001a336100ad565b6daaeb6d7670e522a718067333cd4e3b156100a85760405163a0af290360e01b8152306004820152733cc6cdda760b79bafa08df41ecfa224f810dceb660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401600060405180830381600087803b15801561008f57600080fd5b505af11580156100a3573d6000803e3d6000fd5b505050505b6100fd565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6103398061010c6000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80638da5cb5b116100505780638da5cb5b146100b4578063f2fde38b146100d2578063f9c0611c146100e557600080fd5b806341f434341461006c578063715018a6146100aa575b600080fd5b6100816daaeb6d7670e522a718067333cd4e81565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100b2610100565b005b60005473ffffffffffffffffffffffffffffffffffffffff16610081565b6100b26100e03660046102c6565b610114565b610081733cc6cdda760b79bafa08df41ecfa224f810dceb681565b6101086101d0565b6101126000610251565b565b61011c6101d0565b73ffffffffffffffffffffffffffffffffffffffff81166101c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6101cd81610251565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610112576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101bb565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156102d857600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146102fc57600080fd5b939250505056fea26469706673582212200400eca6cc8b44a23d342000bb74629c1c8358c4828214154d1ec4b34e389c4664736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80638da5cb5b116100505780638da5cb5b146100b4578063f2fde38b146100d2578063f9c0611c146100e557600080fd5b806341f434341461006c578063715018a6146100aa575b600080fd5b6100816daaeb6d7670e522a718067333cd4e81565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100b2610100565b005b60005473ffffffffffffffffffffffffffffffffffffffff16610081565b6100b26100e03660046102c6565b610114565b610081733cc6cdda760b79bafa08df41ecfa224f810dceb681565b6101086101d0565b6101126000610251565b565b61011c6101d0565b73ffffffffffffffffffffffffffffffffffffffff81166101c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6101cd81610251565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610112576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101bb565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156102d857600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146102fc57600080fd5b939250505056fea26469706673582212200400eca6cc8b44a23d342000bb74629c1c8358c4828214154d1ec4b34e389c4664736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "title": "OperatorFilterSubription", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on OpenSea operator filter registry", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4340, + "contract": "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFilterSubscription.sol:OperatorFilterSubscription", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/RoyaltyManager.json b/packages/deploy/deployments/mumbai/RoyaltyManager.json new file mode 100644 index 0000000000..4d57e2bac9 --- /dev/null +++ b/packages/deploy/deployments/mumbai/RoyaltyManager.json @@ -0,0 +1,978 @@ +{ + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "commonRecipient", + "type": "address" + } + ], + "name": "RecipientSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "royaltyBps", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "RoyaltySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "commonSplit", + "type": "uint16" + } + ], + "name": "SplitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "splitterAddress", + "type": "address" + } + ], + "name": "SplitterDeployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newForwarder", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "inputs": [], + "name": "CONTRACT_ROYALTY_SETTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SPLITTER_DEPLOYER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "commonRecipient", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "commonSplit", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "contractRoyalty", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "creatorRoyaltiesSplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + } + ], + "name": "deploySplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "creatorSplitterAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCommonRecipient", + "outputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "bps", + "type": "uint16" + } + ], + "internalType": "struct Recipient", + "name": "recipient", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + } + ], + "name": "getContractRoyalty", + "outputs": [ + { + "internalType": "uint16", + "name": "royaltyBps", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "getCreatorRoyaltySplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "creatorSplitterAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatorSplit", + "outputs": [ + { + "internalType": "uint16", + "name": "creatorSplit", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRoyaltyInfo", + "outputs": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "royaltySplit", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_commonRecipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_commonSplit", + "type": "uint16" + }, + { + "internalType": "address", + "name": "royaltySplitterCloneable", + "type": "address" + }, + { + "internalType": "address", + "name": "managerAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "contractRoyaltySetter", + "type": "address" + }, + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_royaltyBps", + "type": "uint16" + } + ], + "name": "setContractRoyalty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_commonRecipient", + "type": "address" + } + ], + "name": "setRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + } + ], + "name": "setRoyaltyRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_commonSplit", + "type": "uint16" + } + ], + "name": "setSplit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "transactionIndex": 7, + "gasUsed": "868849", + "logsBloom": "0x00002004000000000000000004000000400000020000000000000090000000000202000000008420001000000001000000008000000000000080000000000000000000000000000000000000000802800000000000000000000100040000000000000000020000000000020000042800000000800008000080000000010000000000000040000400000000000000000000000000000080000000800000a00000200000000000000000000000000400000000000000000000901000000001004000000020000000000001004000060000000000000400000100108000001020000000000000080000000000000000001000000000000000000000000000100000", + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936", + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000e7d8e2ce77edc95e930d4e72776b77d0defdb52c" + ], + "data": "0x", + "logIndex": 36, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d479401", + "0x000000000000000000000000a5eb9c9eb4f4c35b9be8cfaaa7909f9ebe6cb609" + ], + "data": "0x", + "logIndex": 37, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0xb8dc7db64fd987e5b05af4eb247387c388b40222e3ecb8c029b8a62227d4d28b" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000001388", + "logIndex": 38, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 39, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0xdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b0", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 40, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0xcf5a353bfd0527e34114d504be74108a364de84a629045c08c104fc5878097df", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7" + ], + "data": "0x", + "logIndex": 41, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 42, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 43, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000f903ba9e006193c1527bfbe65fe2123704ea3f99" + ], + "data": "0x00000000000000000000000000000000000000000000000000079005f13c9b9d00000000000000000000000000000000000000000000000fc01bf3e175ba7cae000000000000000000000000000000000000000000001142a563bd7613f0bb8d00000000000000000000000000000000000000000000000fc01463db847de111000000000000000000000000000000000000000000001142a56b4d7c052d572a", + "logIndex": 44, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + } + ], + "blockNumber": 40238256, + "cumulativeGasUsed": "2671689", + "status": 1, + "byzantium": true + }, + "args": [ + "0xE7D8e2cE77eDC95e930D4E72776b77D0DeFdB52C", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0x0e902f9d000000000000000000000000a5eb9c9eb4f4c35b9be8cfaaa7909f9ebe6cb60900000000000000000000000000000000000000000000000000000000000013880000000000000000000000006ae14ed710f456995e053e0327a7467143ef0e9500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [ + "0xa5Eb9C9Eb4F4c35B9Be8cFaAA7909F9ebe6Cb609", + 5000, + "0x6ae14ED710f456995e053e0327a7467143EF0E95", + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165", + "0x49c4D4C94829B9c44052C5f5Cb164Fc612181165", + "0x69015912aa33720b842dcd6ac059ed623f28d9f7" + ] + }, + "implementation": "0xE7D8e2cE77eDC95e930D4E72776b77D0DeFdB52C", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/RoyaltyManager_Implementation.json b/packages/deploy/deployments/mumbai/RoyaltyManager_Implementation.json new file mode 100644 index 0000000000..512a62b827 --- /dev/null +++ b/packages/deploy/deployments/mumbai/RoyaltyManager_Implementation.json @@ -0,0 +1,1088 @@ +{ + "address": "0xE7D8e2cE77eDC95e930D4E72776b77D0DeFdB52C", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "commonRecipient", + "type": "address" + } + ], + "name": "RecipientSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "royaltyBps", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + } + ], + "name": "RoyaltySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "commonSplit", + "type": "uint16" + } + ], + "name": "SplitSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "splitterAddress", + "type": "address" + } + ], + "name": "SplitterDeployed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousForwarder", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newForwarder", + "type": "address" + } + ], + "name": "TrustedForwarderSet", + "type": "event" + }, + { + "inputs": [], + "name": "CONTRACT_ROYALTY_SETTER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SPLITTER_DEPLOYER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "commonRecipient", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "commonSplit", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "contractRoyalty", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "creatorRoyaltiesSplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + } + ], + "name": "deploySplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "creatorSplitterAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCommonRecipient", + "outputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "bps", + "type": "uint16" + } + ], + "internalType": "struct Recipient", + "name": "recipient", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contractAddress", + "type": "address" + } + ], + "name": "getContractRoyalty", + "outputs": [ + { + "internalType": "uint16", + "name": "royaltyBps", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "getCreatorRoyaltySplitter", + "outputs": [ + { + "internalType": "address payable", + "name": "creatorSplitterAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCreatorSplit", + "outputs": [ + { + "internalType": "uint16", + "name": "creatorSplit", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRoyaltyInfo", + "outputs": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "royaltySplit", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrustedForwarder", + "outputs": [ + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_commonRecipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_commonSplit", + "type": "uint16" + }, + { + "internalType": "address", + "name": "royaltySplitterCloneable", + "type": "address" + }, + { + "internalType": "address", + "name": "managerAdmin", + "type": "address" + }, + { + "internalType": "address", + "name": "contractRoyaltySetter", + "type": "address" + }, + { + "internalType": "address", + "name": "trustedForwarder", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_royaltyBps", + "type": "uint16" + } + ], + "name": "setContractRoyalty", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_commonRecipient", + "type": "address" + } + ], + "name": "setRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + } + ], + "name": "setRoyaltyRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_commonSplit", + "type": "uint16" + } + ], + "name": "setSplit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_newForwarder", + "type": "address" + } + ], + "name": "setTrustedForwarder", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x6d7e11a523442215d2fad9ce5ef4183f59976f62c59102e114b5061660d4d074", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0xE7D8e2cE77eDC95e930D4E72776b77D0DeFdB52C", + "transactionIndex": 9, + "gasUsed": "1392689", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000180000000000000200000200000000000000000000000000400000000000000000000000080000000004000000000000000000001000000040000000000000000000000108040000000000000000000020000000000000000000000000000000000000000000000100000", + "blockHash": "0x240e658d04317e341e14558dff017a582ff9d058ccbb5bebae19954ef7045f7a", + "transactionHash": "0x6d7e11a523442215d2fad9ce5ef4183f59976f62c59102e114b5061660d4d074", + "logs": [ + { + "transactionIndex": 9, + "blockNumber": 40238253, + "transactionHash": "0x6d7e11a523442215d2fad9ce5ef4183f59976f62c59102e114b5061660d4d074", + "address": "0xE7D8e2cE77eDC95e930D4E72776b77D0DeFdB52C", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 58, + "blockHash": "0x240e658d04317e341e14558dff017a582ff9d058ccbb5bebae19954ef7045f7a" + }, + { + "transactionIndex": 9, + "blockNumber": 40238253, + "transactionHash": "0x6d7e11a523442215d2fad9ce5ef4183f59976f62c59102e114b5061660d4d074", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000076bf703b0ff0000000000000000000000000000000000000000000000000fc0235fd87aff3f51000000000000000000000000000000000000000000003472ae3e3785d400251c00000000000000000000000000000000000000000000000fc01bf3e1774e4051000000000000000000000000000000000000000000003472ae45a37cd7b1241c", + "logIndex": 59, + "blockHash": "0x240e658d04317e341e14558dff017a582ff9d058ccbb5bebae19954ef7045f7a" + } + ], + "blockNumber": 40238253, + "cumulativeGasUsed": "3221810", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "467ad2aa755667473a7c4622090bf333", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"commonRecipient\",\"type\":\"address\"}],\"name\":\"RecipientSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"royaltyBps\",\"type\":\"uint16\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"}],\"name\":\"RoyaltySet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"commonSplit\",\"type\":\"uint16\"}],\"name\":\"SplitSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"splitterAddress\",\"type\":\"address\"}],\"name\":\"SplitterDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousForwarder\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newForwarder\",\"type\":\"address\"}],\"name\":\"TrustedForwarderSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"CONTRACT_ROYALTY_SETTER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SPLITTER_DEPLOYER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commonRecipient\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"commonSplit\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"contractRoyalty\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"creatorRoyaltiesSplitter\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"deploySplitter\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"creatorSplitterAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCommonRecipient\",\"outputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"bps\",\"type\":\"uint16\"}],\"internalType\":\"struct Recipient\",\"name\":\"recipient\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_contractAddress\",\"type\":\"address\"}],\"name\":\"getContractRoyalty\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"royaltyBps\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"}],\"name\":\"getCreatorRoyaltySplitter\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"creatorSplitterAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCreatorSplit\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"creatorSplit\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRoyaltyInfo\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"royaltySplit\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTrustedForwarder\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"trustedForwarder\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_commonRecipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"_commonSplit\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"royaltySplitterCloneable\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"managerAdmin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractRoyaltySetter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"trustedForwarder\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"_royaltyBps\",\"type\":\"uint16\"}],\"name\":\"setContractRoyalty\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_commonRecipient\",\"type\":\"address\"}],\"name\":\"setRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"setRoyaltyRecipient\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"_commonSplit\",\"type\":\"uint16\"}],\"name\":\"setSplit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newForwarder\",\"type\":\"address\"}],\"name\":\"setTrustedForwarder\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"},\"RoleAdminChanged(bytes32,bytes32,bytes32)\":{\"details\":\"Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._\"},\"RoleGranted(bytes32,address,address)\":{\"details\":\"Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}.\"},\"RoleRevoked(bytes32,address,address)\":{\"details\":\"Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"this protects the implementation contract from behing initialized.\"},\"deploySplitter(address,address)\":{\"details\":\"should only called once per creator\",\"params\":{\"creator\":\"the address of the creator\",\"recipient\":\"the wallet of the recipient where they would receive their royalty\"},\"returns\":{\"creatorSplitterAddress\":\"splitter's address deployed for a creator\"}},\"getCommonRecipient()\":{\"returns\":{\"recipient\":\"which has the common recipient and split\"}},\"getContractRoyalty(address)\":{\"params\":{\"_contractAddress\":\"the address of the contract for which the royalty is required\"},\"returns\":{\"royaltyBps\":\"royalty bps of the contract\"}},\"getCreatorRoyaltySplitter(address)\":{\"params\":{\"creator\":\"the address of the creator\"},\"returns\":{\"creatorSplitterAddress\":\"splitter's address deployed for a creator\"}},\"getCreatorSplit()\":{\"returns\":{\"creatorSplit\":\"which is 10000 - commonSplit\"}},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoyaltyInfo()\":{\"returns\":{\"recipient\":\"address of common royalty recipient\",\"royaltySplit\":\"contract EIP2981 royalty bps\"}},\"getTrustedForwarder()\":{\"returns\":{\"trustedForwarder\":\"address of current TrustedForwarder\"}},\"grantRole(bytes32,address)\":{\"details\":\"Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event.\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"initialize(address,uint16,address,address,address,address)\":{\"details\":\"called during the deployment via the proxy.\",\"params\":{\"_commonRecipient\":\"the != address(0)common recipient for all the splitters\",\"_commonSplit\":\"split for the common recipient's and creator split would be 10000 - commonSplit\",\"contractRoyaltySetter\":\"the address of royalty setter of contract.\",\"managerAdmin\":\"address of RoyaltyManager contract.\",\"royaltySplitterCloneable\":\"address of cloneable splitter contract for royalties distribution\",\"trustedForwarder\":\"the trustedForwarder address for royalty splitters to use.\"}},\"renounceRole(bytes32,address)\":{\"details\":\"Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event.\"},\"revokeRole(bytes32,address)\":{\"details\":\"Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event.\"},\"setContractRoyalty(address,uint16)\":{\"details\":\"can only be called by contract royalty setter.\",\"params\":{\"_royaltyBps\":\"the royalty split for the EIP 2981\",\"contractAddress\":\"address of contract for which royalty is set\"}},\"setRecipient(address)\":{\"details\":\"can only be called by the admin\",\"params\":{\"_commonRecipient\":\"is the common recipient for all the splitters\"}},\"setRoyaltyRecipient(address)\":{\"details\":\"should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\",\"params\":{\"recipient\":\"new recipient wallet.\"}},\"setSplit(uint16)\":{\"details\":\"can only be called by the admin.\",\"params\":{\"_commonSplit\":\"split for the common recipient and creators split would be 10000 - commonSplit\"}},\"setTrustedForwarder(address)\":{\"details\":\"can only be called by the admin new splitters will read this value\",\"params\":{\"_newForwarder\":\"is the new trusted forwarder address\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"title\":\"RoyaltyManager\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"deploySplitter(address,address)\":{\"notice\":\"deploys splitter for creator\"},\"getCommonRecipient()\":{\"notice\":\"to be called by the splitters to get the common recipient and split\"},\"getContractRoyalty(address)\":{\"notice\":\"returns the EIP2981 royalty bps\"},\"getCreatorRoyaltySplitter(address)\":{\"notice\":\"returns the address of splitter of a creator.\"},\"getCreatorSplit()\":{\"notice\":\"returns the amount of basis points allocated to the creator\"},\"getRoyaltyInfo()\":{\"notice\":\"returns the commonRecipient and EIP2981 royalty bps\"},\"getTrustedForwarder()\":{\"notice\":\"get the current trustedForwarder address\"},\"initialize(address,uint16,address,address,address,address)\":{\"notice\":\"initialization function for the deployment of contract\"},\"setContractRoyalty(address,uint16)\":{\"notice\":\"called to set the EIP 2981 royalty split\"},\"setRecipient(address)\":{\"notice\":\"sets the common recipient\"},\"setRoyaltyRecipient(address)\":{\"notice\":\"sets royalty recipient wallet\"},\"setSplit(uint16)\":{\"notice\":\"sets the common split\"},\"setTrustedForwarder(address)\":{\"notice\":\"sets the trustedForwarder address to be used by the splitters\"}},\"notice\":\"Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info for contracts that don't use the RoyaltySplitter.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\":\"RoyaltyManager\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @notice A library for manipulation of byte arrays.\\n */\\nlibrary BytesLibrary {\\n /**\\n * @dev Replace the address at the given location in a byte array if the contents at that location\\n * match the expected address.\\n */\\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\\n internal\\n pure\\n {\\n bytes memory expectedData = abi.encodePacked(expectedAddress);\\n bytes memory newData = abi.encodePacked(newAddress);\\n // An address is 20 bytes long\\n for (uint256 i = 0; i < 20; i++) {\\n uint256 dataLocation = startLocation + i;\\n require(data[dataLocation] == expectedData[i], \\\"Bytes: Data provided does not include the expectedAddress\\\");\\n data[dataLocation] = newData[i];\\n }\\n }\\n\\n /**\\n * @dev Checks if the call data starts with the given function signature.\\n */\\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\\n // A signature is 4 bytes long\\n if (callData.length < 4) {\\n return false;\\n }\\n for (uint256 i = 0; i < 4; i++) {\\n if (callData[i] != functionSig[i]) {\\n return false;\\n }\\n }\\n\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x73fd074a57bd5d185ffb79dd98bb8db2e97c2d7df064d83f3f42da15ab9da8a1\",\"license\":\"MIT OR Apache-2.0\"},\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/// @author: manifold.xyz\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\nstruct Recipient {\\n address payable recipient;\\n uint16 bps;\\n}\\n\\ninterface IRoyaltySplitter is IERC165 {\\n /**\\n * @dev Set the splitter recipients. Total bps must total 10000.\\n */\\n function setRecipients(Recipient[] calldata recipients) external;\\n\\n /**\\n * @dev Get the splitter recipients;\\n */\\n function getRecipients() external view returns (Recipient[] memory);\\n}\\n\",\"keccak256\":\"0xc507963f66c4238d25e69d2d05ac5995c549aa89789e89e7a556403221547c6d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlUpgradeable.sol\\\";\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../utils/StringsUpgradeable.sol\\\";\\nimport \\\"../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```solidity\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```solidity\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\\n * to enforce additional security measures for this role.\\n */\\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\\n function __AccessControl_init() internal onlyInitializing {\\n }\\n\\n function __AccessControl_init_unchained() internal onlyInitializing {\\n }\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role);\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\\n * Overriding this function changes the behavior of the {onlyRole} modifier.\\n *\\n * Format of the revert message is described in {_checkRole}.\\n *\\n * _Available since v4.6._\\n */\\n function _checkRole(bytes32 role) internal view virtual {\\n _checkRole(role, _msgSender());\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view virtual {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n StringsUpgradeable.toHexString(account),\\n \\\" is missing role \\\",\\n StringsUpgradeable.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * May emit a {RoleGranted} event.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n *\\n * NOTE: This function is deprecated in favor of {_grantRole}.\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleGranted} event.\\n */\\n function _grantRole(bytes32 role, address account) internal virtual {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * Internal function without access restriction.\\n *\\n * May emit a {RoleRevoked} event.\\n */\\n function _revokeRole(bytes32 role, address account) internal virtual {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xfeefb24d068524440e1ba885efdf105d91f83504af3c2d745ffacc4595396831\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControlUpgradeable {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xb8f5302f12138c5561362e88a78d061573e6298b7a1a5afe84a1e2c8d4d5aeaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\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 * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\\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\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\\\";\\nimport \\\"./math/SignedMathUpgradeable.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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\":\"0xb96dc79b65b7c37937919dcdb356a969ce0aa2e8338322bf4dc027a3c9c9a7eb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\\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\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\\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\":\"0x2bc0007987c229ae7624eb29be6a9b84f6a6a5872f76248b15208b131ea41c4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\\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\":\"0x88f6b7bba3ee33eeb741f9a0f5bc98b6e6e352d0fe4905377bb328590f84095a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Clones.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\\n * deploying minimal proxy contracts, also known as \\\"clones\\\".\\n *\\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\\n *\\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\\n * deterministic method.\\n *\\n * _Available since v3.4._\\n */\\nlibrary Clones {\\n /**\\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\\n *\\n * This function uses the create opcode, which should never revert.\\n */\\n function clone(address implementation) internal returns (address instance) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\\n // of the `implementation` address with the bytecode before the address.\\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\\n instance := create(0, 0x09, 0x37)\\n }\\n require(instance != address(0), \\\"ERC1167: create failed\\\");\\n }\\n\\n /**\\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\\n *\\n * This function uses the create2 opcode and a `salt` to deterministically deploy\\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\\n * the clones cannot be deployed twice at the same address.\\n */\\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\\n // of the `implementation` address with the bytecode before the address.\\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\\n instance := create2(0, 0x09, 0x37, salt)\\n }\\n require(instance != address(0), \\\"ERC1167: create2 failed\\\");\\n }\\n\\n /**\\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\\n */\\n function predictDeterministicAddress(\\n address implementation,\\n bytes32 salt,\\n address deployer\\n ) internal pure returns (address predicted) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(add(ptr, 0x38), deployer)\\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\\n mstore(add(ptr, 0x14), implementation)\\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\\n mstore(add(ptr, 0x58), salt)\\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\\n predicted := keccak256(add(ptr, 0x43), 0x55)\\n }\\n }\\n\\n /**\\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\\n */\\n function predictDeterministicAddress(\\n address implementation,\\n bytes32 salt\\n ) internal view returns (address predicted) {\\n return predictDeterministicAddress(implementation, salt, address(this));\\n }\\n}\\n\",\"keccak256\":\"0x01f055f5c26ba25d7f83e9aa9ba877fbea4d0bf22227de046ea67494bc932999\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"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\"},\"@openzeppelin/contracts/utils/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n// CAUTION\\n// This version of SafeMath should only be used with Solidity 0.8 or later,\\n// because it relies on the compiler's built in overflow checks.\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations.\\n *\\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\\n * now has built in overflow checking.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator.\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n unchecked {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x58b21219689909c4f8339af00813760337f7e2e7f169a97fe49e2896dcfb3b9a\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\nabstract contract ERC2771HandlerAbstract {\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function isTrustedForwarder(address forwarder) external view returns (bool) {\\n return _isTrustedForwarder(forwarder);\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual returns (address sender) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n // The assembly code is more direct than the Solidity version using `abi.decode`.\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\\n }\\n } else {\\n sender = msg.sender;\\n }\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual returns (bytes calldata) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n return msg.data[:msg.data.length - 20];\\n } else {\\n return msg.data;\\n }\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n /// @dev this function must be IMPLEMENTED\\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xc4f349865ea7146f51b69f1edacdef60e0a2a7cf4dab538a5ae53ee9a0036231\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity ^0.8.0;\\n\\nimport {AccessControlUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\\\";\\nimport {IRoyaltyManager} from \\\"./interfaces/IRoyaltyManager.sol\\\";\\nimport {Recipient} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\nimport {RoyaltySplitter} from \\\"./RoyaltySplitter.sol\\\";\\nimport {Clones} from \\\"@openzeppelin/contracts/proxy/Clones.sol\\\";\\n\\n/// @title RoyaltyManager\\n/// @author The Sandbox\\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\\n/// for contracts that don't use the RoyaltySplitter.\\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\\\"CONTRACT_ROYALTY_SETTER_ROLE\\\");\\n bytes32 public constant SPLITTER_DEPLOYER_ROLE = keccak256(\\\"SPLITTER_DEPLOYER_ROLE\\\");\\n\\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\\n uint16 public commonSplit;\\n address payable public commonRecipient;\\n mapping(address => uint16) public contractRoyalty;\\n mapping(address => address payable) public creatorRoyaltiesSplitter;\\n address internal _royaltySplitterCloneable;\\n address internal _trustedForwarder;\\n\\n /// @dev this protects the implementation contract from behing initialized.\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @notice initialization function for the deployment of contract\\n /// @dev called during the deployment via the proxy.\\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\\n /// @param managerAdmin address of RoyaltyManager contract.\\n /// @param contractRoyaltySetter the address of royalty setter of contract.\\n /// @param trustedForwarder the trustedForwarder address for royalty splitters to use.\\n function initialize(\\n address payable _commonRecipient,\\n uint16 _commonSplit,\\n address royaltySplitterCloneable,\\n address managerAdmin,\\n address contractRoyaltySetter,\\n address trustedForwarder\\n ) external initializer {\\n _setRecipient(_commonRecipient);\\n _setSplit(_commonSplit);\\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\\n _royaltySplitterCloneable = royaltySplitterCloneable;\\n _setTrustedForwarder(trustedForwarder);\\n }\\n\\n /// @notice sets royalty recipient wallet\\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\\n /// @param recipient new recipient wallet.\\n function setRoyaltyRecipient(address payable recipient) external {\\n address payable _creatorSplitterAddress = creatorRoyaltiesSplitter[msg.sender];\\n require(_creatorSplitterAddress != address(0), \\\"Manager: No splitter deployed for the creator\\\");\\n address _recipient = RoyaltySplitter(_creatorSplitterAddress).recipient();\\n require(_recipient != recipient, \\\"Manager: Recipient already set\\\");\\n Recipient[] memory newRecipient = new Recipient[](1);\\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\\n RoyaltySplitter(_creatorSplitterAddress).setRecipients(newRecipient);\\n }\\n\\n /// @notice sets the common recipient\\n /// @dev can only be called by the admin\\n /// @param _commonRecipient is the common recipient for all the splitters\\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\\n _setRecipient(_commonRecipient);\\n }\\n\\n /// @notice sets the trustedForwarder address to be used by the splitters\\n /// @dev can only be called by the admin\\n /// new splitters will read this value\\n /// @param _newForwarder is the new trusted forwarder address\\n function setTrustedForwarder(address _newForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\\n _setTrustedForwarder(_newForwarder);\\n }\\n\\n /// @notice sets the common split\\n /// @dev can only be called by the admin.\\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\\n _setSplit(_commonSplit);\\n }\\n\\n /// @notice get the current trustedForwarder address\\n /// @return trustedForwarder address of current TrustedForwarder\\n function getTrustedForwarder() external view returns (address trustedForwarder) {\\n return _trustedForwarder;\\n }\\n\\n function _setRecipient(address payable _commonRecipient) internal {\\n require(_commonRecipient != address(0), \\\"Manager: Can't set common recipient to zero address\\\");\\n commonRecipient = _commonRecipient;\\n emit RecipientSet(_commonRecipient);\\n }\\n\\n function _setSplit(uint16 _commonSplit) internal {\\n require(_commonSplit < TOTAL_BASIS_POINTS, \\\"Manager: Can't set split greater than the total basis point\\\");\\n commonSplit = _commonSplit;\\n emit SplitSet(_commonSplit);\\n }\\n\\n /// @notice sets trusted forwarder address\\n /// @param _newForwarder new trusted forwarder address to set\\n function _setTrustedForwarder(address _newForwarder) internal {\\n address oldTrustedForwarder = _trustedForwarder;\\n _trustedForwarder = _newForwarder;\\n emit TrustedForwarderSet(oldTrustedForwarder, _newForwarder);\\n }\\n\\n /// @notice called to set the EIP 2981 royalty split\\n /// @dev can only be called by contract royalty setter.\\n /// @param contractAddress address of contract for which royalty is set\\n /// @param _royaltyBps the royalty split for the EIP 2981\\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\\n external\\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\\n {\\n require(_royaltyBps < TOTAL_BASIS_POINTS, \\\"Manager: Royalty can't be greater than Total base points\\\");\\n contractRoyalty[contractAddress] = _royaltyBps;\\n emit RoyaltySet(_royaltyBps, contractAddress);\\n }\\n\\n /// @notice to be called by the splitters to get the common recipient and split\\n /// @return recipient which has the common recipient and split\\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\\n return Recipient({recipient: commonRecipient, bps: commonSplit});\\n }\\n\\n /// @notice deploys splitter for creator\\n /// @dev should only called once per creator\\n /// @param creator the address of the creator\\n /// @param recipient the wallet of the recipient where they would receive their royalty\\n /// @return creatorSplitterAddress splitter's address deployed for a creator\\n function deploySplitter(address creator, address payable recipient)\\n external\\n onlyRole(SPLITTER_DEPLOYER_ROLE)\\n returns (address payable creatorSplitterAddress)\\n {\\n creatorSplitterAddress = creatorRoyaltiesSplitter[creator];\\n if (creatorSplitterAddress == address(0)) {\\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\\n creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\\n emit SplitterDeployed(creator, recipient, creatorSplitterAddress);\\n }\\n return creatorSplitterAddress;\\n }\\n\\n /// @notice returns the address of splitter of a creator.\\n /// @param creator the address of the creator\\n /// @return creatorSplitterAddress splitter's address deployed for a creator\\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress) {\\n return creatorRoyaltiesSplitter[creator];\\n }\\n\\n /// @notice returns the amount of basis points allocated to the creator\\n /// @return creatorSplit which is 10000 - commonSplit\\n function getCreatorSplit() external view returns (uint16 creatorSplit) {\\n return TOTAL_BASIS_POINTS - commonSplit;\\n }\\n\\n /// @notice returns the commonRecipient and EIP2981 royalty bps\\n /// @return recipient address of common royalty recipient\\n /// @return royaltySplit contract EIP2981 royalty bps\\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit) {\\n return (commonRecipient, contractRoyalty[msg.sender]);\\n }\\n\\n /// @notice returns the EIP2981 royalty bps\\n /// @param _contractAddress the address of the contract for which the royalty is required\\n /// @return royaltyBps royalty bps of the contract\\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) {\\n return contractRoyalty[_contractAddress];\\n }\\n\\n uint256[44] private __gap;\\n}\\n\",\"keccak256\":\"0xa4cb3105eb4293e27bd54e46d52fd85479a665dae6749d86816adb9ce0c02c85\",\"license\":\"MIT OR Apache-2.0\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {\\n OwnableUpgradeable,\\n ContextUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {AddressUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\\\";\\nimport {ERC165Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\\\";\\nimport {SafeMath} from \\\"@openzeppelin/contracts/utils/math/SafeMath.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {BytesLibrary} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\\\";\\nimport {\\n IRoyaltySplitter,\\n IERC165,\\n Recipient\\n} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\nimport {ERC2771HandlerAbstract} from \\\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\\\";\\nimport {IRoyaltyManager} from \\\"./interfaces/IRoyaltyManager.sol\\\";\\nimport {IERC20Approve} from \\\"./interfaces/IERC20Approve.sol\\\";\\n\\n/// @title RoyaltySplitter\\n/// @author The Sandbox\\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\\ncontract RoyaltySplitter is\\n Initializable,\\n OwnableUpgradeable,\\n IRoyaltySplitter,\\n ERC165Upgradeable,\\n ERC2771HandlerAbstract\\n{\\n using BytesLibrary for bytes;\\n using AddressUpgradeable for address payable;\\n using AddressUpgradeable for address;\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\\n\\n address payable public recipient;\\n IRoyaltyManager public royaltyManager;\\n\\n event ETHTransferred(address indexed account, uint256 amount);\\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\\n event RecipientSet(address indexed recipientAddress);\\n\\n /// @dev this protects the implementation contract from behing initialized.\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @notice Query if a contract implements interface `id`.\\n /// @param interfaceId the interface identifier, as specified in ERC-165.\\n /// @return isSupported `true` if the contract implements `id`.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(IERC165, ERC165Upgradeable)\\n returns (bool isSupported)\\n {\\n return (interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId));\\n }\\n\\n /// @notice initialize the contract\\n /// @dev can only be run once.\\n /// @param recipientAddress the wallet of the creator when the contract is deployed\\n /// @param _royaltyManager the address of the royalty manager contract\\n function initialize(address payable recipientAddress, address _royaltyManager) external initializer {\\n royaltyManager = IRoyaltyManager(_royaltyManager); // set manager before Ownable_init for _isTrustedForwarder\\n _setRecipient(recipientAddress);\\n __Ownable_init();\\n __ERC165_init();\\n }\\n\\n /// @notice sets recipient for the splitter\\n /// @dev only the owner can call this.\\n /// @param recipients the array of recipients which should only have one recipient.\\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\\n require(recipients.length == 1, \\\"Invalid recipents length\\\");\\n _setRecipient(recipients[0].recipient);\\n }\\n\\n function _setRecipient(address payable recipientAddress) private {\\n recipient = recipientAddress;\\n emit RecipientSet(recipientAddress);\\n }\\n\\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\\n /// @return recipients array of royalty recipients through the splitter and their splits of royalty.\\n function getRecipients() external view override returns (Recipient[] memory recipients) {\\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\\n recipients = new Recipient[](2);\\n recipients[0].recipient = recipient;\\n recipients[0].bps = creatorSplit;\\n recipients[1] = commonRecipient;\\n return recipients;\\n }\\n\\n /// @notice Splits and forwards ETH to the royalty receivers\\n /// @dev splits ETH every time it is sent to this contract as royalty.\\n receive() external payable {\\n _splitETH(msg.value);\\n }\\n\\n /// @notice Splits and forwards ETH to the royalty receivers\\n /// @dev normally ETH should be split automatically by receive function.\\n function splitETH() external payable {\\n _splitETH(address(this).balance);\\n }\\n\\n function _splitETH(uint256 value) internal {\\n if (value > 0) {\\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\\n Recipient[] memory _recipients = new Recipient[](2);\\n _recipients[0].recipient = recipient;\\n _recipients[0].bps = creatorSplit;\\n _recipients[1] = commonRecipient;\\n uint256 totalSent;\\n uint256 amountToSend;\\n unchecked {\\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\\n Recipient memory _recipient = _recipients[i];\\n amountToSend = (value * _recipient.bps) / TOTAL_BASIS_POINTS;\\n totalSent += amountToSend;\\n _recipient.recipient.sendValue(amountToSend);\\n emit ETHTransferred(_recipient.recipient, amountToSend);\\n }\\n // Favor the 1st recipient if there are any rounding issues\\n amountToSend = value - totalSent;\\n }\\n _recipients[0].recipient.sendValue(amountToSend);\\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\\n }\\n }\\n\\n /// @notice split ERC20 Tokens owned by this contract.\\n /// @dev can only be called by one of the recipients\\n /// @param erc20Contract the address of the tokens to be split.\\n function splitERC20Tokens(IERC20 erc20Contract) external {\\n require(_splitERC20Tokens(erc20Contract), \\\"Split: ERC20 split failed\\\");\\n }\\n\\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool success) {\\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\\n if (balance == 0) {\\n return false;\\n }\\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\\n require(\\n commonRecipient.recipient == _msgSender() || recipient == _msgSender(),\\n \\\"Split: Can only be called by one of the recipients\\\"\\n );\\n Recipient[] memory _recipients = new Recipient[](2);\\n _recipients[0].recipient = recipient;\\n _recipients[0].bps = creatorSplit;\\n _recipients[1] = commonRecipient;\\n uint256 amountToSend;\\n uint256 totalSent;\\n unchecked {\\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\\n Recipient memory _recipient = _recipients[i];\\n (success, amountToSend) = balance.tryMul(_recipient.bps);\\n require(success, \\\"RoyaltySplitter: Multiplication Overflow\\\");\\n\\n amountToSend /= TOTAL_BASIS_POINTS;\\n totalSent += amountToSend;\\n\\n erc20Contract.safeTransfer(_recipient.recipient, amountToSend);\\n emit ERC20Transferred(address(erc20Contract), _recipient.recipient, amountToSend);\\n }\\n // Favor the 1st recipient if there are any rounding issues\\n amountToSend = balance - totalSent;\\n }\\n erc20Contract.safeTransfer(_recipients[0].recipient, amountToSend);\\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\\n return true;\\n } catch {\\n return false;\\n }\\n }\\n\\n /// @notice verify whether a forwarder address is the trustedForwarder address, using the manager setting\\n /// @dev this function is used to avoid having a trustedForwarder variable inside the splitter\\n /// @return isTrusted bool whether the forwarder is the trusted address\\n function _isTrustedForwarder(address forwarder)\\n internal\\n view\\n override(ERC2771HandlerAbstract)\\n returns (bool isTrusted)\\n {\\n return (forwarder == royaltyManager.getTrustedForwarder());\\n }\\n\\n function _msgSender()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerAbstract)\\n returns (address sender)\\n {\\n return ERC2771HandlerAbstract._msgSender();\\n }\\n\\n function _msgData()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerAbstract)\\n returns (bytes calldata messageData)\\n {\\n return ERC2771HandlerAbstract._msgData();\\n }\\n}\\n\",\"keccak256\":\"0xa077e9197363476de46c2fa2651b0ed201b20b1b93bde6a0615a2b8e4e380dbc\",\"license\":\"MIT OR Apache-2.0\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n///@title IERC20Approve\\n///@notice Interface for ERC20 token approval operations\\ninterface IERC20Approve {\\n ///@notice Approves the specified spender to spend up to the given amount of tokens on behalf of the sender\\n ///@param spender The address that is allowed to spend tokens\\n ///@param amount The maximum amount of tokens that the spender is allowed to spend\\n ///@return `true` if the approval was successful, otherwise `false`\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n ///@notice Increases the allowance granted to the specified spender by the given amount\\n ///@param spender The address that is allowed to spend tokens\\n ///@param amount The additional amount of tokens that the spender is allowed to spend\\n ///@return `true` if the increase in allowance was successful, otherwise `false`\\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc4e88d5c1caf1a8171d8ee1d82326a4cdf0e05667a61ab4360c71a1b53198f3e\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Recipient} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\n\\n/// @title IRoyaltyManager\\n/// @notice interface for RoyaltyManager Contract\\ninterface IRoyaltyManager {\\n event RecipientSet(address indexed commonRecipient);\\n\\n event SplitSet(uint16 commonSplit);\\n\\n event RoyaltySet(uint16 royaltyBps, address indexed contractAddress);\\n\\n event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder);\\n\\n event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress);\\n\\n ///@notice sets the common recipient\\n ///@param _commonRecipient is the common recipient for all the splitters\\n function setRecipient(address payable _commonRecipient) external;\\n\\n ///@notice sets the common split\\n ///@param commonSplit split for the common recipient\\n function setSplit(uint16 commonSplit) external;\\n\\n ///@notice to be called by the splitters to get the common recipient and split\\n ///@return recipient which has the common recipient and split\\n function getCommonRecipient() external view returns (Recipient memory recipient);\\n\\n ///@notice returns the amount of basis points allocated to the creator\\n ///@return creatorSplit the share of creator in bps\\n function getCreatorSplit() external view returns (uint16 creatorSplit);\\n\\n ///@notice returns the commonRecipient and EIP2981 royalty split\\n ///@return recipient address of common royalty recipient\\n ///@return royaltySplit contract EIP2981 royalty bps\\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit);\\n\\n ///@notice deploys splitter for creator\\n ///@param creator the address of the creator\\n ///@param recipient the wallet of the recipient where they would receive their royalty\\n ///@return creatorSplitterAddress splitter's address deployed for creator\\n function deploySplitter(address creator, address payable recipient)\\n external\\n returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the address of splitter of a creator.\\n ///@param creator the address of the creator\\n ///@return creatorSplitterAddress splitter's address deployed for a creator\\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the EIP2981 royalty split\\n ///@param _contractAddress the address of the contract for which the royalty is required\\n ///@return royaltyBps royalty bps of the contract\\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\\n\\n ///@notice sets the trustedForwarder address to be used by the splitters\\n ///@param _newForwarder is the new trusted forwarder address\\n function setTrustedForwarder(address _newForwarder) external;\\n\\n ///@notice get the current trustedForwarder address\\n ///@return trustedForwarder address of current trusted Forwarder\\n function getTrustedForwarder() external view returns (address trustedForwarder);\\n}\\n\",\"keccak256\":\"0x5e8e149845df288a5d0ddfa00407ebda15d024e8caf1057822670a5232fee93f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6117d5806100ec6000396000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c8063733fc03d116100ee578063ce1b815f11610097578063da74222811610071578063da74222814610471578063db06fff514610484578063ee48cd1b146104b0578063f06040b4146104d757600080fd5b8063ce1b815f1461043a578063d0b72b931461044b578063d547741f1461045e57600080fd5b8063a217fddf116100c8578063a217fddf146103d5578063a86a28d1146103dd578063c0bd4cdd1461041657600080fd5b8063733fc03d146103445780638b49fde71461035757806391d148541461039c57600080fd5b80632b8d5d771161015b5780633bbed4a0116101355780633bbed4a0146102ef57806341e42f301461030257806366cb206314610315578063706ec2fe1461033c57600080fd5b80632b8d5d771461029c5780632f2ff15d146102c957806336568abe146102dc57600080fd5b806315a86f5e1161018c57806315a86f5e14610211578063248a9ca3146102425780632725b15b1461027357600080fd5b806301ffc9a7146101b35780630e902f9d146101db57806311edb735146101f0575b600080fd5b6101c66101c1366004611399565b6104ea565b60405190151581526020015b60405180910390f35b6101ee6101e9366004611402565b610583565b005b6097546101fe9061ffff1681565b60405161ffff90911681526020016101d2565b60975461022a906201000090046001600160a01b031681565b6040516001600160a01b0390911681526020016101d2565b610265610250366004611482565b60009081526065602052604090206001015490565b6040519081526020016101d2565b61022a61028136600461149b565b6099602052600090815260409020546001600160a01b031681565b6101fe6102aa36600461149b565b6001600160a01b031660009081526098602052604090205461ffff1690565b6101ee6102d73660046114b8565b61071e565b6101ee6102ea3660046114b8565b610748565b6101ee6102fd36600461149b565b6107d4565b6101ee61031036600461149b565b6107e8565b6102657fdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b081565b6101fe610a39565b6101ee6103523660046114e8565b610a54565b604080518082018252600080825260209182015281518083019092526097546001600160a01b0362010000820416835261ffff16908201526040516101d29190611503565b6101c66103aa3660046114b8565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610265600081565b60975433600090815260986020908152604091829020548251620100009094046001600160a01b0316845261ffff1690830152016101d2565b6101fe61042436600461149b565b60986020526000908152604090205461ffff1681565b609b546001600160a01b031661022a565b6101ee610459366004611527565b610a68565b6101ee61046c3660046114b8565b610b70565b6101ee61047f36600461149b565b610b95565b61022a61049236600461149b565b6001600160a01b039081166000908152609960205260409020541690565b6102657fffb8dcece2f6b64cef8fad984b08e00059761f3f3f446db4dc9a4d398a6c19d581565b61022a6104e536600461155c565b610ba9565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061057d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600054610100900460ff16158080156105a35750600054600160ff909116105b806105bd5750303b1580156105bd575060005460ff166001145b6106345760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff191660011790558015610657576000805461ff0019166101001790555b61066087610d05565b61066986610deb565b610674600085610eb0565b61069e7fdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b084610eb0565b609a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387161790556106cf82610f52565b8015610715576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60008281526065602052604090206001015461073981610fb1565b6107438383610eb0565b505050565b6001600160a01b03811633146107c65760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161062b565b6107d08282610fbe565b5050565b60006107df81610fb1565b6107d082610d05565b336000908152609960205260409020546001600160a01b0316806108745760405162461bcd60e51b815260206004820152602d60248201527f4d616e616765723a204e6f2073706c6974746572206465706c6f79656420666f60448201527f72207468652063726561746f7200000000000000000000000000000000000000606482015260840161062b565b6000816001600160a01b03166366d003ac6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d8919061158a565b9050826001600160a01b0316816001600160a01b03160361093b5760405162461bcd60e51b815260206004820152601e60248201527f4d616e616765723a20526563697069656e7420616c7265616479207365740000604482015260640161062b565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109525790505090506040518060400160405280856001600160a01b03168152602001600061ffff16815250816000815181106109b1576109b16115bd565b60209081029190910101526040517fc1426d0e0000000000000000000000000000000000000000000000000000000081526001600160a01b0384169063c1426d0e90610a019084906004016115d3565b600060405180830381600087803b158015610a1b57600080fd5b505af1158015610a2f573d6000803e3d6000fd5b5050505050505050565b609754600090610a4f9061ffff1661271061164d565b905090565b6000610a5f81610fb1565b6107d082610deb565b7fdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b0610a9281610fb1565b61271061ffff831610610b0d5760405162461bcd60e51b815260206004820152603860248201527f4d616e616765723a20526f79616c74792063616e27742062652067726561746560448201527f72207468616e20546f74616c206261736520706f696e74730000000000000000606482015260840161062b565b6001600160a01b038316600081815260986020908152604091829020805461ffff191661ffff871690811790915591519182527f7f9762123fb25c27c3aa0ecf56eeed3e1518bc8ee29086c7ff5dd6238a37c264910160405180910390a2505050565b600082815260656020526040902060010154610b8b81610fb1565b6107438383610fbe565b6000610ba081610fb1565b6107d082610f52565b60007fffb8dcece2f6b64cef8fad984b08e00059761f3f3f446db4dc9a4d398a6c19d5610bd581610fb1565b6001600160a01b0380851660009081526099602052604090205416915081610cfe57609a54610c0c906001600160a01b0316611041565b6040517f485cc9550000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301523060248301529193509083169063485cc95590604401600060405180830381600087803b158015610c7257600080fd5b505af1158015610c86573d6000803e3d6000fd5b505050506001600160a01b03848116600081815260996020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19168786169081179091559151918252928616927f211fb797e8cc89486cf94b6bbcdf623b9742b3f191823122a2fa93e9589a6d24910160405180910390a35b5092915050565b6001600160a01b038116610d815760405162461bcd60e51b815260206004820152603360248201527f4d616e616765723a2043616e27742073657420636f6d6d6f6e2072656369706960448201527f656e7420746f207a65726f206164647265737300000000000000000000000000606482015260840161062b565b609780547fffffffffffffffffffff0000000000000000000000000000000000000000ffff16620100006001600160a01b038416908102919091179091556040517f9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d47940190600090a250565b61271061ffff821610610e665760405162461bcd60e51b815260206004820152603b60248201527f4d616e616765723a2043616e2774207365742073706c6974206772656174657260448201527f207468616e2074686520746f74616c20626173697320706f696e740000000000606482015260840161062b565b6097805461ffff191661ffff83169081179091556040519081527fb8dc7db64fd987e5b05af4eb247387c388b40222e3ecb8c029b8a62227d4d28b9060200160405180910390a150565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff166107d05760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610f0e3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b609b80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907fcf5a353bfd0527e34114d504be74108a364de84a629045c08c104fc5878097df90600090a35050565b610fbb81336110e2565b50565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16156107d05760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b0381166110dd5760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c656400000000000000000000604482015260640161062b565b919050565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff166107d05761111581611157565b611120836020611169565b60405160200161113192919061168c565b60408051601f198184030181529082905262461bcd60e51b825261062b9160040161170d565b606061057d6001600160a01b03831660145b60606000611178836002611740565b611183906002611757565b67ffffffffffffffff81111561119b5761119b6115a7565b6040519080825280601f01601f1916602001820160405280156111c5576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106111fc576111fc6115bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061125f5761125f6115bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061129b846002611740565b6112a6906001611757565b90505b6001811115611343577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106112e7576112e76115bd565b1a60f81b8282815181106112fd576112fd6115bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361133c8161176a565b90506112a9565b5083156113925760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161062b565b9392505050565b6000602082840312156113ab57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461139257600080fd5b6001600160a01b0381168114610fbb57600080fd5b803561ffff811681146110dd57600080fd5b60008060008060008060c0878903121561141b57600080fd5b8635611426816113db565b9550611434602088016113f0565b94506040870135611444816113db565b93506060870135611454816113db565b92506080870135611464816113db565b915060a0870135611474816113db565b809150509295509295509295565b60006020828403121561149457600080fd5b5035919050565b6000602082840312156114ad57600080fd5b8135611392816113db565b600080604083850312156114cb57600080fd5b8235915060208301356114dd816113db565b809150509250929050565b6000602082840312156114fa57600080fd5b611392826113f0565b81516001600160a01b0316815260208083015161ffff16908201526040810161057d565b6000806040838503121561153a57600080fd5b8235611545816113db565b9150611553602084016113f0565b90509250929050565b6000806040838503121561156f57600080fd5b823561157a816113db565b915060208301356114dd816113db565b60006020828403121561159c57600080fd5b8151611392816113db565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101561162a5761161a84835180516001600160a01b0316825260209081015161ffff16910152565b92840192908501906001016115f0565b5091979650505050505050565b634e487b7160e01b600052601160045260246000fd5b61ffff828116828216039080821115610cfe57610cfe611637565b60005b8381101561168357818101518382015260200161166b565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516116c4816017850160208801611668565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611701816028840160208801611668565b01602801949350505050565b602081526000825180602084015261172c816040850160208701611668565b601f01601f19169190910160400192915050565b808202811582820484141761057d5761057d611637565b8082018082111561057d5761057d611637565b60008161177957611779611637565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212207ce46be84564048823760430e2801740f9e93b2a5d6b64509a4876e8aa1ffa2864736f6c63430008120033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c8063733fc03d116100ee578063ce1b815f11610097578063da74222811610071578063da74222814610471578063db06fff514610484578063ee48cd1b146104b0578063f06040b4146104d757600080fd5b8063ce1b815f1461043a578063d0b72b931461044b578063d547741f1461045e57600080fd5b8063a217fddf116100c8578063a217fddf146103d5578063a86a28d1146103dd578063c0bd4cdd1461041657600080fd5b8063733fc03d146103445780638b49fde71461035757806391d148541461039c57600080fd5b80632b8d5d771161015b5780633bbed4a0116101355780633bbed4a0146102ef57806341e42f301461030257806366cb206314610315578063706ec2fe1461033c57600080fd5b80632b8d5d771461029c5780632f2ff15d146102c957806336568abe146102dc57600080fd5b806315a86f5e1161018c57806315a86f5e14610211578063248a9ca3146102425780632725b15b1461027357600080fd5b806301ffc9a7146101b35780630e902f9d146101db57806311edb735146101f0575b600080fd5b6101c66101c1366004611399565b6104ea565b60405190151581526020015b60405180910390f35b6101ee6101e9366004611402565b610583565b005b6097546101fe9061ffff1681565b60405161ffff90911681526020016101d2565b60975461022a906201000090046001600160a01b031681565b6040516001600160a01b0390911681526020016101d2565b610265610250366004611482565b60009081526065602052604090206001015490565b6040519081526020016101d2565b61022a61028136600461149b565b6099602052600090815260409020546001600160a01b031681565b6101fe6102aa36600461149b565b6001600160a01b031660009081526098602052604090205461ffff1690565b6101ee6102d73660046114b8565b61071e565b6101ee6102ea3660046114b8565b610748565b6101ee6102fd36600461149b565b6107d4565b6101ee61031036600461149b565b6107e8565b6102657fdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b081565b6101fe610a39565b6101ee6103523660046114e8565b610a54565b604080518082018252600080825260209182015281518083019092526097546001600160a01b0362010000820416835261ffff16908201526040516101d29190611503565b6101c66103aa3660046114b8565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b610265600081565b60975433600090815260986020908152604091829020548251620100009094046001600160a01b0316845261ffff1690830152016101d2565b6101fe61042436600461149b565b60986020526000908152604090205461ffff1681565b609b546001600160a01b031661022a565b6101ee610459366004611527565b610a68565b6101ee61046c3660046114b8565b610b70565b6101ee61047f36600461149b565b610b95565b61022a61049236600461149b565b6001600160a01b039081166000908152609960205260409020541690565b6102657fffb8dcece2f6b64cef8fad984b08e00059761f3f3f446db4dc9a4d398a6c19d581565b61022a6104e536600461155c565b610ba9565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061057d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b600054610100900460ff16158080156105a35750600054600160ff909116105b806105bd5750303b1580156105bd575060005460ff166001145b6106345760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff191660011790558015610657576000805461ff0019166101001790555b61066087610d05565b61066986610deb565b610674600085610eb0565b61069e7fdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b084610eb0565b609a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387161790556106cf82610f52565b8015610715576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60008281526065602052604090206001015461073981610fb1565b6107438383610eb0565b505050565b6001600160a01b03811633146107c65760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161062b565b6107d08282610fbe565b5050565b60006107df81610fb1565b6107d082610d05565b336000908152609960205260409020546001600160a01b0316806108745760405162461bcd60e51b815260206004820152602d60248201527f4d616e616765723a204e6f2073706c6974746572206465706c6f79656420666f60448201527f72207468652063726561746f7200000000000000000000000000000000000000606482015260840161062b565b6000816001600160a01b03166366d003ac6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d8919061158a565b9050826001600160a01b0316816001600160a01b03160361093b5760405162461bcd60e51b815260206004820152601e60248201527f4d616e616765723a20526563697069656e7420616c7265616479207365740000604482015260640161062b565b604080516001808252818301909252600091816020015b60408051808201909152600080825260208201528152602001906001900390816109525790505090506040518060400160405280856001600160a01b03168152602001600061ffff16815250816000815181106109b1576109b16115bd565b60209081029190910101526040517fc1426d0e0000000000000000000000000000000000000000000000000000000081526001600160a01b0384169063c1426d0e90610a019084906004016115d3565b600060405180830381600087803b158015610a1b57600080fd5b505af1158015610a2f573d6000803e3d6000fd5b5050505050505050565b609754600090610a4f9061ffff1661271061164d565b905090565b6000610a5f81610fb1565b6107d082610deb565b7fdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b0610a9281610fb1565b61271061ffff831610610b0d5760405162461bcd60e51b815260206004820152603860248201527f4d616e616765723a20526f79616c74792063616e27742062652067726561746560448201527f72207468616e20546f74616c206261736520706f696e74730000000000000000606482015260840161062b565b6001600160a01b038316600081815260986020908152604091829020805461ffff191661ffff871690811790915591519182527f7f9762123fb25c27c3aa0ecf56eeed3e1518bc8ee29086c7ff5dd6238a37c264910160405180910390a2505050565b600082815260656020526040902060010154610b8b81610fb1565b6107438383610fbe565b6000610ba081610fb1565b6107d082610f52565b60007fffb8dcece2f6b64cef8fad984b08e00059761f3f3f446db4dc9a4d398a6c19d5610bd581610fb1565b6001600160a01b0380851660009081526099602052604090205416915081610cfe57609a54610c0c906001600160a01b0316611041565b6040517f485cc9550000000000000000000000000000000000000000000000000000000081526001600160a01b0385811660048301523060248301529193509083169063485cc95590604401600060405180830381600087803b158015610c7257600080fd5b505af1158015610c86573d6000803e3d6000fd5b505050506001600160a01b03848116600081815260996020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19168786169081179091559151918252928616927f211fb797e8cc89486cf94b6bbcdf623b9742b3f191823122a2fa93e9589a6d24910160405180910390a35b5092915050565b6001600160a01b038116610d815760405162461bcd60e51b815260206004820152603360248201527f4d616e616765723a2043616e27742073657420636f6d6d6f6e2072656369706960448201527f656e7420746f207a65726f206164647265737300000000000000000000000000606482015260840161062b565b609780547fffffffffffffffffffff0000000000000000000000000000000000000000ffff16620100006001600160a01b038416908102919091179091556040517f9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d47940190600090a250565b61271061ffff821610610e665760405162461bcd60e51b815260206004820152603b60248201527f4d616e616765723a2043616e2774207365742073706c6974206772656174657260448201527f207468616e2074686520746f74616c20626173697320706f696e740000000000606482015260840161062b565b6097805461ffff191661ffff83169081179091556040519081527fb8dc7db64fd987e5b05af4eb247387c388b40222e3ecb8c029b8a62227d4d28b9060200160405180910390a150565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff166107d05760008281526065602090815260408083206001600160a01b03851684529091529020805460ff19166001179055610f0e3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b609b80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907fcf5a353bfd0527e34114d504be74108a364de84a629045c08c104fc5878097df90600090a35050565b610fbb81336110e2565b50565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff16156107d05760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b0381166110dd5760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c656400000000000000000000604482015260640161062b565b919050565b60008281526065602090815260408083206001600160a01b038516845290915290205460ff166107d05761111581611157565b611120836020611169565b60405160200161113192919061168c565b60408051601f198184030181529082905262461bcd60e51b825261062b9160040161170d565b606061057d6001600160a01b03831660145b60606000611178836002611740565b611183906002611757565b67ffffffffffffffff81111561119b5761119b6115a7565b6040519080825280601f01601f1916602001820160405280156111c5576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106111fc576111fc6115bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061125f5761125f6115bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061129b846002611740565b6112a6906001611757565b90505b6001811115611343577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106112e7576112e76115bd565b1a60f81b8282815181106112fd576112fd6115bd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361133c8161176a565b90506112a9565b5083156113925760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161062b565b9392505050565b6000602082840312156113ab57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461139257600080fd5b6001600160a01b0381168114610fbb57600080fd5b803561ffff811681146110dd57600080fd5b60008060008060008060c0878903121561141b57600080fd5b8635611426816113db565b9550611434602088016113f0565b94506040870135611444816113db565b93506060870135611454816113db565b92506080870135611464816113db565b915060a0870135611474816113db565b809150509295509295509295565b60006020828403121561149457600080fd5b5035919050565b6000602082840312156114ad57600080fd5b8135611392816113db565b600080604083850312156114cb57600080fd5b8235915060208301356114dd816113db565b809150509250929050565b6000602082840312156114fa57600080fd5b611392826113f0565b81516001600160a01b0316815260208083015161ffff16908201526040810161057d565b6000806040838503121561153a57600080fd5b8235611545816113db565b9150611553602084016113f0565b90509250929050565b6000806040838503121561156f57600080fd5b823561157a816113db565b915060208301356114dd816113db565b60006020828403121561159c57600080fd5b8151611392816113db565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000919060409081850190868401855b8281101561162a5761161a84835180516001600160a01b0316825260209081015161ffff16910152565b92840192908501906001016115f0565b5091979650505050505050565b634e487b7160e01b600052601160045260246000fd5b61ffff828116828216039080821115610cfe57610cfe611637565b60005b8381101561168357818101518382015260200161166b565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516116c4816017850160208801611668565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611701816028840160208801611668565b01602801949350505050565b602081526000825180602084015261172c816040850160208701611668565b601f01601f19169190910160400192915050565b808202811582820484141761057d5761057d611637565b8082018082111561057d5761057d611637565b60008161177957611779611637565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212207ce46be84564048823760430e2801740f9e93b2a5d6b64509a4876e8aa1ffa2864736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "events": { + "Initialized(uint8)": { + "details": "Triggered when the contract has been initialized or reinitialized." + }, + "RoleAdminChanged(bytes32,bytes32,bytes32)": { + "details": "Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite {RoleAdminChanged} not being emitted signaling this. _Available since v3.1._" + }, + "RoleGranted(bytes32,address,address)": { + "details": "Emitted when `account` is granted `role`. `sender` is the account that originated the contract call, an admin role bearer except when using {AccessControl-_setupRole}." + }, + "RoleRevoked(bytes32,address,address)": { + "details": "Emitted when `account` is revoked `role`. `sender` is the account that originated the contract call: - if using `revokeRole`, it is the admin role bearer - if using `renounceRole`, it is the role bearer (i.e. `account`)" + } + }, + "kind": "dev", + "methods": { + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor", + "details": "this protects the implementation contract from behing initialized." + }, + "deploySplitter(address,address)": { + "details": "should only called once per creator", + "params": { + "creator": "the address of the creator", + "recipient": "the wallet of the recipient where they would receive their royalty" + }, + "returns": { + "creatorSplitterAddress": "splitter's address deployed for a creator" + } + }, + "getCommonRecipient()": { + "returns": { + "recipient": "which has the common recipient and split" + } + }, + "getContractRoyalty(address)": { + "params": { + "_contractAddress": "the address of the contract for which the royalty is required" + }, + "returns": { + "royaltyBps": "royalty bps of the contract" + } + }, + "getCreatorRoyaltySplitter(address)": { + "params": { + "creator": "the address of the creator" + }, + "returns": { + "creatorSplitterAddress": "splitter's address deployed for a creator" + } + }, + "getCreatorSplit()": { + "returns": { + "creatorSplit": "which is 10000 - commonSplit" + } + }, + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getRoyaltyInfo()": { + "returns": { + "recipient": "address of common royalty recipient", + "royaltySplit": "contract EIP2981 royalty bps" + } + }, + "getTrustedForwarder()": { + "returns": { + "trustedForwarder": "address of current TrustedForwarder" + } + }, + "grantRole(bytes32,address)": { + "details": "Grants `role` to `account`. If `account` had not been already granted `role`, emits a {RoleGranted} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleGranted} event." + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "initialize(address,uint16,address,address,address,address)": { + "details": "called during the deployment via the proxy.", + "params": { + "_commonRecipient": "the != address(0)common recipient for all the splitters", + "_commonSplit": "split for the common recipient's and creator split would be 10000 - commonSplit", + "contractRoyaltySetter": "the address of royalty setter of contract.", + "managerAdmin": "address of RoyaltyManager contract.", + "royaltySplitterCloneable": "address of cloneable splitter contract for royalties distribution", + "trustedForwarder": "the trustedForwarder address for royalty splitters to use." + } + }, + "renounceRole(bytes32,address)": { + "details": "Revokes `role` from the calling account. Roles are often managed via {grantRole} and {revokeRole}: this function's purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced). If the calling account had been revoked `role`, emits a {RoleRevoked} event. Requirements: - the caller must be `account`. May emit a {RoleRevoked} event." + }, + "revokeRole(bytes32,address)": { + "details": "Revokes `role` from `account`. If `account` had been granted `role`, emits a {RoleRevoked} event. Requirements: - the caller must have ``role``'s admin role. May emit a {RoleRevoked} event." + }, + "setContractRoyalty(address,uint16)": { + "details": "can only be called by contract royalty setter.", + "params": { + "_royaltyBps": "the royalty split for the EIP 2981", + "contractAddress": "address of contract for which royalty is set" + } + }, + "setRecipient(address)": { + "details": "can only be called by the admin", + "params": { + "_commonRecipient": "is the common recipient for all the splitters" + } + }, + "setRoyaltyRecipient(address)": { + "details": "should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.", + "params": { + "recipient": "new recipient wallet." + } + }, + "setSplit(uint16)": { + "details": "can only be called by the admin.", + "params": { + "_commonSplit": "split for the common recipient and creators split would be 10000 - commonSplit" + } + }, + "setTrustedForwarder(address)": { + "details": "can only be called by the admin new splitters will read this value", + "params": { + "_newForwarder": "is the new trusted forwarder address" + } + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + } + }, + "title": "RoyaltyManager", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "deploySplitter(address,address)": { + "notice": "deploys splitter for creator" + }, + "getCommonRecipient()": { + "notice": "to be called by the splitters to get the common recipient and split" + }, + "getContractRoyalty(address)": { + "notice": "returns the EIP2981 royalty bps" + }, + "getCreatorRoyaltySplitter(address)": { + "notice": "returns the address of splitter of a creator." + }, + "getCreatorSplit()": { + "notice": "returns the amount of basis points allocated to the creator" + }, + "getRoyaltyInfo()": { + "notice": "returns the commonRecipient and EIP2981 royalty bps" + }, + "getTrustedForwarder()": { + "notice": "get the current trustedForwarder address" + }, + "initialize(address,uint16,address,address,address,address)": { + "notice": "initialization function for the deployment of contract" + }, + "setContractRoyalty(address,uint16)": { + "notice": "called to set the EIP 2981 royalty split" + }, + "setRecipient(address)": { + "notice": "sets the common recipient" + }, + "setRoyaltyRecipient(address)": { + "notice": "sets royalty recipient wallet" + }, + "setSplit(uint16)": { + "notice": "sets the common split" + }, + "setTrustedForwarder(address)": { + "notice": "sets the trustedForwarder address to be used by the splitters" + } + }, + "notice": "Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info for contracts that don't use the RoyaltySplitter.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 686, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 689, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1219, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 1492, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "__gap", + "offset": 0, + "slot": "51", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 178, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "_roles", + "offset": 0, + "slot": "101", + "type": "t_mapping(t_bytes32,t_struct(RoleData)173_storage)" + }, + { + "astId": 473, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "__gap", + "offset": 0, + "slot": "102", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 3815, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "commonSplit", + "offset": 0, + "slot": "151", + "type": "t_uint16" + }, + { + "astId": 3817, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "commonRecipient", + "offset": 2, + "slot": "151", + "type": "t_address_payable" + }, + { + "astId": 3821, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "contractRoyalty", + "offset": 0, + "slot": "152", + "type": "t_mapping(t_address,t_uint16)" + }, + { + "astId": 3825, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "creatorRoyaltiesSplitter", + "offset": 0, + "slot": "153", + "type": "t_mapping(t_address,t_address_payable)" + }, + { + "astId": 3827, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "_royaltySplitterCloneable", + "offset": 0, + "slot": "154", + "type": "t_address" + }, + { + "astId": 3829, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "_trustedForwarder", + "offset": 0, + "slot": "155", + "type": "t_address" + }, + { + "astId": 4231, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "__gap", + "offset": 0, + "slot": "156", + "type": "t_array(t_uint256)44_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_address_payable": { + "encoding": "inplace", + "label": "address payable", + "numberOfBytes": "20" + }, + "t_array(t_uint256)44_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[44]", + "numberOfBytes": "1408" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address_payable)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address payable)", + "numberOfBytes": "32", + "value": "t_address_payable" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_uint16)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint16)", + "numberOfBytes": "32", + "value": "t_uint16" + }, + "t_mapping(t_bytes32,t_struct(RoleData)173_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControlUpgradeable.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)173_storage" + }, + "t_struct(RoleData)173_storage": { + "encoding": "inplace", + "label": "struct AccessControlUpgradeable.RoleData", + "members": [ + { + "astId": 170, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 172, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol:RoyaltyManager", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_uint16": { + "encoding": "inplace", + "label": "uint16", + "numberOfBytes": "2" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/RoyaltyManager_Proxy.json b/packages/deploy/deployments/mumbai/RoyaltyManager_Proxy.json new file mode 100644 index 0000000000..52365e22b4 --- /dev/null +++ b/packages/deploy/deployments/mumbai/RoyaltyManager_Proxy.json @@ -0,0 +1,331 @@ +{ + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "transactionIndex": 7, + "gasUsed": "868849", + "logsBloom": "0x00002004000000000000000004000000400000020000000000000090000000000202000000008420001000000001000000008000000000000080000000000000000000000000000000000000000802800000000000000000000100040000000000000000020000000000020000042800000000800008000080000000010000000000000040000400000000000000000000000000000080000000800000a00000200000000000000000000000000400000000000000000000901000000001004000000020000000000001004000060000000000000400000100108000001020000000000000080000000000000000001000000000000000000000000000100000", + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936", + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000e7d8e2ce77edc95e930d4e72776b77d0defdb52c" + ], + "data": "0x", + "logIndex": 36, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d479401", + "0x000000000000000000000000a5eb9c9eb4f4c35b9be8cfaaa7909f9ebe6cb609" + ], + "data": "0x", + "logIndex": 37, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0xb8dc7db64fd987e5b05af4eb247387c388b40222e3ecb8c029b8a62227d4d28b" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000001388", + "logIndex": 38, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 39, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0xdcb0f28d7542ec49daa994e65691b787109a3a17ef48e6216b254a4f7b5b53b0", + "0x00000000000000000000000049c4d4c94829b9c44052c5f5cb164fc612181165", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02" + ], + "data": "0x", + "logIndex": 40, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0xcf5a353bfd0527e34114d504be74108a364de84a629045c08c104fc5878097df", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7" + ], + "data": "0x", + "logIndex": 41, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 42, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0xc7A0bFc1DF5c9cA04ef63C1eA2F18aF2FBF6DA21", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045023af7b33994a22740bc51c3ca90a7ed82e124", + "logIndex": 43, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + }, + { + "transactionIndex": 7, + "blockNumber": 40238256, + "transactionHash": "0xb89fbf5d6f122393160d0d861d2768ebcdd65ec7b378a128634aa9aa177cd2ea", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000f903ba9e006193c1527bfbe65fe2123704ea3f99" + ], + "data": "0x00000000000000000000000000000000000000000000000000079005f13c9b9d00000000000000000000000000000000000000000000000fc01bf3e175ba7cae000000000000000000000000000000000000000000001142a563bd7613f0bb8d00000000000000000000000000000000000000000000000fc01463db847de111000000000000000000000000000000000000000000001142a56b4d7c052d572a", + "logIndex": 44, + "blockHash": "0xd5587cd238a7145a26f3c2cb2ae70e8c0ada9fa9ecff4c6ce27fa201fcfab936" + } + ], + "blockNumber": 40238256, + "cumulativeGasUsed": "2671689", + "status": 1, + "byzantium": true + }, + "args": [ + "0xE7D8e2cE77eDC95e930D4E72776b77D0DeFdB52C", + "0x45023af7B33994a22740Bc51C3Ca90A7Ed82e124", + "0x0e902f9d000000000000000000000000a5eb9c9eb4f4c35b9be8cfaaa7909f9ebe6cb60900000000000000000000000000000000000000000000000000000000000013880000000000000000000000006ae14ed710f456995e053e0327a7467143ef0e9500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000049c4d4c94829b9c44052c5f5cb164fc61218116500000000000000000000000069015912aa33720b842dcd6ac059ed623f28d9f7" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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\\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\",\"keccak256\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/RoyaltySplitter.json b/packages/deploy/deployments/mumbai/RoyaltySplitter.json new file mode 100644 index 0000000000..16cf4e0106 --- /dev/null +++ b/packages/deploy/deployments/mumbai/RoyaltySplitter.json @@ -0,0 +1,547 @@ +{ + "address": "0x6ae14ED710f456995e053e0327a7467143EF0E95", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "erc20Contract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ERC20Transferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ETHTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipientAddress", + "type": "address" + } + ], + "name": "RecipientSet", + "type": "event" + }, + { + "inputs": [], + "name": "getRecipients", + "outputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "bps", + "type": "uint16" + } + ], + "internalType": "struct Recipient[]", + "name": "recipients", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "recipientAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_royaltyManager", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "forwarder", + "type": "address" + } + ], + "name": "isTrustedForwarder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "recipient", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "royaltyManager", + "outputs": [ + { + "internalType": "contract IRoyaltyManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint16", + "name": "bps", + "type": "uint16" + } + ], + "internalType": "struct Recipient[]", + "name": "recipients", + "type": "tuple[]" + } + ], + "name": "setRecipients", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "erc20Contract", + "type": "address" + } + ], + "name": "splitERC20Tokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "splitETH", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "isSupported", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x5f25e81efe2c39479d690544fa7743936a9dd99905d27ad7f3ca4d3c4f493d77", + "receipt": { + "to": null, + "from": "0x5F890c9522dCE5670d741D4277BFCC2d9cA8Af02", + "contractAddress": "0x6ae14ED710f456995e053e0327a7467143EF0E95", + "transactionIndex": 13, + "gasUsed": "1592134", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000020000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000200000200000000000000008000000000400000000000000000000000000000000044000000000000000000001000000040000000000000000000000108040000000000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x776768f28813d53ac72b30c6c76073826b3ec23e785e461acd4c95adb6aab865", + "transactionHash": "0x5f25e81efe2c39479d690544fa7743936a9dd99905d27ad7f3ca4d3c4f493d77", + "logs": [ + { + "transactionIndex": 13, + "blockNumber": 40238250, + "transactionHash": "0x5f25e81efe2c39479d690544fa7743936a9dd99905d27ad7f3ca4d3c4f493d77", + "address": "0x6ae14ED710f456995e053e0327a7467143EF0E95", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000ff", + "logIndex": 70, + "blockHash": "0x776768f28813d53ac72b30c6c76073826b3ec23e785e461acd4c95adb6aab865" + }, + { + "transactionIndex": 13, + "blockNumber": 40238250, + "transactionHash": "0x5f25e81efe2c39479d690544fa7743936a9dd99905d27ad7f3ca4d3c4f493d77", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000005f890c9522dce5670d741d4277bfcc2d9ca8af02", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000087c0e605a254600000000000000000000000000000000000000000000000fc02bdbe6dd26fac9000000000000000000000000000000000000000000003472ad5b962d2c049e0900000000000000000000000000000000000000000000000fc0235fd87cccd583000000000000000000000000000000000000000000003472ad64123b8c5ec34f", + "logIndex": 71, + "blockHash": "0x776768f28813d53ac72b30c6c76073826b3ec23e785e461acd4c95adb6aab865" + } + ], + "blockNumber": 40238250, + "cumulativeGasUsed": "3375438", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "467ad2aa755667473a7c4622090bf333", + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"erc20Contract\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ERC20Transferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"ETHTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipientAddress\",\"type\":\"address\"}],\"name\":\"RecipientSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"getRecipients\",\"outputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"bps\",\"type\":\"uint16\"}],\"internalType\":\"struct Recipient[]\",\"name\":\"recipients\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"recipientAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_royaltyManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"forwarder\",\"type\":\"address\"}],\"name\":\"isTrustedForwarder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"recipient\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"royaltyManager\",\"outputs\":[{\"internalType\":\"contract IRoyaltyManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address payable\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"bps\",\"type\":\"uint16\"}],\"internalType\":\"struct Recipient[]\",\"name\":\"recipients\",\"type\":\"tuple[]\"}],\"name\":\"setRecipients\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"erc20Contract\",\"type\":\"address\"}],\"name\":\"splitERC20Tokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"splitETH\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isSupported\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"The Sandbox\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"details\":\"this protects the implementation contract from behing initialized.\"},\"getRecipients()\":{\"returns\":{\"recipients\":\"array of royalty recipients through the splitter and their splits of royalty.\"}},\"initialize(address,address)\":{\"details\":\"can only be run once.\",\"params\":{\"_royaltyManager\":\"the address of the royalty manager contract\",\"recipientAddress\":\"the wallet of the creator when the contract is deployed\"}},\"isTrustedForwarder(address)\":{\"params\":{\"forwarder\":\"trusted forwarder address to check\"},\"returns\":{\"_0\":\"true if the address is the same as the trusted forwarder\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setRecipients((address,uint16)[])\":{\"details\":\"only the owner can call this.\",\"params\":{\"recipients\":\"the array of recipients which should only have one recipient.\"}},\"splitERC20Tokens(address)\":{\"details\":\"can only be called by one of the recipients\",\"params\":{\"erc20Contract\":\"the address of the tokens to be split.\"}},\"splitETH()\":{\"details\":\"normally ETH should be split automatically by receive function.\"},\"supportsInterface(bytes4)\":{\"params\":{\"interfaceId\":\"the interface identifier, as specified in ERC-165.\"},\"returns\":{\"isSupported\":\"`true` if the contract implements `id`.\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"RoyaltySplitter\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getRecipients()\":{\"notice\":\"to get recipients of royalty through this splitter and their splits of royalty.\"},\"initialize(address,address)\":{\"notice\":\"initialize the contract\"},\"isTrustedForwarder(address)\":{\"notice\":\"return true if the forwarder is the trusted forwarder\"},\"setRecipients((address,uint16)[])\":{\"notice\":\"sets recipient for the splitter\"},\"splitERC20Tokens(address)\":{\"notice\":\"split ERC20 Tokens owned by this contract.\"},\"splitETH()\":{\"notice\":\"Splits and forwards ETH to the royalty receivers\"},\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements interface `id`.\"}},\"notice\":\"RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\":\"RoyaltySplitter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @notice A library for manipulation of byte arrays.\\n */\\nlibrary BytesLibrary {\\n /**\\n * @dev Replace the address at the given location in a byte array if the contents at that location\\n * match the expected address.\\n */\\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\\n internal\\n pure\\n {\\n bytes memory expectedData = abi.encodePacked(expectedAddress);\\n bytes memory newData = abi.encodePacked(newAddress);\\n // An address is 20 bytes long\\n for (uint256 i = 0; i < 20; i++) {\\n uint256 dataLocation = startLocation + i;\\n require(data[dataLocation] == expectedData[i], \\\"Bytes: Data provided does not include the expectedAddress\\\");\\n data[dataLocation] = newData[i];\\n }\\n }\\n\\n /**\\n * @dev Checks if the call data starts with the given function signature.\\n */\\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\\n // A signature is 4 bytes long\\n if (callData.length < 4) {\\n return false;\\n }\\n for (uint256 i = 0; i < 4; i++) {\\n if (callData[i] != functionSig[i]) {\\n return false;\\n }\\n }\\n\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x73fd074a57bd5d185ffb79dd98bb8db2e97c2d7df064d83f3f42da15ab9da8a1\",\"license\":\"MIT OR Apache-2.0\"},\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/// @author: manifold.xyz\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\nstruct Recipient {\\n address payable recipient;\\n uint16 bps;\\n}\\n\\ninterface IRoyaltySplitter is IERC165 {\\n /**\\n * @dev Set the splitter recipients. Total bps must total 10000.\\n */\\n function setRecipients(Recipient[] calldata recipients) external;\\n\\n /**\\n * @dev Get the splitter recipients;\\n */\\n function getRecipients() external view returns (Recipient[] memory);\\n}\\n\",\"keccak256\":\"0xc507963f66c4238d25e69d2d05ac5995c549aa89789e89e7a556403221547c6d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\\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 function __Ownable_init() internal onlyInitializing {\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal onlyInitializing {\\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 * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x4075622496acc77fd6d4de4cc30a8577a744d5c75afad33fdeacf1704d6eda98\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized != type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0x89be10e757d242e9b18d5a32c9fbe2019f6d63052bbe46397a430a1d60d7f794\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\\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\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165Upgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165Upgradeable).interfaceId;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x9a3b990bd56d139df3e454a9edf1c64668530b5a77fc32eb063bc206f958274a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\\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\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xec63854014a5b4f2b3290ab9103a21bdf902a508d0f41a8573fea49e98bf571a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n _callOptionalReturn(token, approvalCall);\\n }\\n }\\n\\n /**\\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n * Revert on invalid signature.\\n */\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n *\\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return\\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\\n }\\n}\\n\",\"keccak256\":\"0xabefac93435967b4d36a4fabcbdbb918d1f0b7ae3c3d85bc30923b326c927ed1\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"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\"},\"@openzeppelin/contracts/utils/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n// CAUTION\\n// This version of SafeMath should only be used with Solidity 0.8 or later,\\n// because it relies on the compiler's built in overflow checks.\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations.\\n *\\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\\n * now has built in overflow checking.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a + b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a * b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator.\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n unchecked {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n unchecked {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x58b21219689909c4f8339af00813760337f7e2e7f169a97fe49e2896dcfb3b9a\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n/// @dev minimal ERC2771 handler to keep bytecode-size down\\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\\nabstract contract ERC2771HandlerAbstract {\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n function isTrustedForwarder(address forwarder) external view returns (bool) {\\n return _isTrustedForwarder(forwarder);\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\\n /// @return sender the calculated address of the sender\\n function _msgSender() internal view virtual returns (address sender) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n // The assembly code is more direct than the Solidity version using `abi.decode`.\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\\n }\\n } else {\\n sender = msg.sender;\\n }\\n }\\n\\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\\n /// @return the calldata without the sender\\n function _msgData() internal view virtual returns (bytes calldata) {\\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\\n return msg.data[:msg.data.length - 20];\\n } else {\\n return msg.data;\\n }\\n }\\n\\n /// @notice return true if the forwarder is the trusted forwarder\\n /// @param forwarder trusted forwarder address to check\\n /// @return true if the address is the same as the trusted forwarder\\n /// @dev this function must be IMPLEMENTED\\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\\n}\\n\",\"keccak256\":\"0xc4f349865ea7146f51b69f1edacdef60e0a2a7cf4dab538a5ae53ee9a0036231\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\":{\"content\":\"// SPDX-License-Identifier: MIT OR Apache-2.0\\npragma solidity ^0.8.0;\\n\\nimport {Initializable} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {\\n OwnableUpgradeable,\\n ContextUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {AddressUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\\\";\\nimport {ERC165Upgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\\\";\\nimport {SafeMath} from \\\"@openzeppelin/contracts/utils/math/SafeMath.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {BytesLibrary} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\\\";\\nimport {\\n IRoyaltySplitter,\\n IERC165,\\n Recipient\\n} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\nimport {ERC2771HandlerAbstract} from \\\"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\\\";\\nimport {IRoyaltyManager} from \\\"./interfaces/IRoyaltyManager.sol\\\";\\nimport {IERC20Approve} from \\\"./interfaces/IERC20Approve.sol\\\";\\n\\n/// @title RoyaltySplitter\\n/// @author The Sandbox\\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\\ncontract RoyaltySplitter is\\n Initializable,\\n OwnableUpgradeable,\\n IRoyaltySplitter,\\n ERC165Upgradeable,\\n ERC2771HandlerAbstract\\n{\\n using BytesLibrary for bytes;\\n using AddressUpgradeable for address payable;\\n using AddressUpgradeable for address;\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\\n\\n address payable public recipient;\\n IRoyaltyManager public royaltyManager;\\n\\n event ETHTransferred(address indexed account, uint256 amount);\\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\\n event RecipientSet(address indexed recipientAddress);\\n\\n /// @dev this protects the implementation contract from behing initialized.\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() {\\n _disableInitializers();\\n }\\n\\n /// @notice Query if a contract implements interface `id`.\\n /// @param interfaceId the interface identifier, as specified in ERC-165.\\n /// @return isSupported `true` if the contract implements `id`.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(IERC165, ERC165Upgradeable)\\n returns (bool isSupported)\\n {\\n return (interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId));\\n }\\n\\n /// @notice initialize the contract\\n /// @dev can only be run once.\\n /// @param recipientAddress the wallet of the creator when the contract is deployed\\n /// @param _royaltyManager the address of the royalty manager contract\\n function initialize(address payable recipientAddress, address _royaltyManager) external initializer {\\n royaltyManager = IRoyaltyManager(_royaltyManager); // set manager before Ownable_init for _isTrustedForwarder\\n _setRecipient(recipientAddress);\\n __Ownable_init();\\n __ERC165_init();\\n }\\n\\n /// @notice sets recipient for the splitter\\n /// @dev only the owner can call this.\\n /// @param recipients the array of recipients which should only have one recipient.\\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\\n require(recipients.length == 1, \\\"Invalid recipents length\\\");\\n _setRecipient(recipients[0].recipient);\\n }\\n\\n function _setRecipient(address payable recipientAddress) private {\\n recipient = recipientAddress;\\n emit RecipientSet(recipientAddress);\\n }\\n\\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\\n /// @return recipients array of royalty recipients through the splitter and their splits of royalty.\\n function getRecipients() external view override returns (Recipient[] memory recipients) {\\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\\n recipients = new Recipient[](2);\\n recipients[0].recipient = recipient;\\n recipients[0].bps = creatorSplit;\\n recipients[1] = commonRecipient;\\n return recipients;\\n }\\n\\n /// @notice Splits and forwards ETH to the royalty receivers\\n /// @dev splits ETH every time it is sent to this contract as royalty.\\n receive() external payable {\\n _splitETH(msg.value);\\n }\\n\\n /// @notice Splits and forwards ETH to the royalty receivers\\n /// @dev normally ETH should be split automatically by receive function.\\n function splitETH() external payable {\\n _splitETH(address(this).balance);\\n }\\n\\n function _splitETH(uint256 value) internal {\\n if (value > 0) {\\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\\n Recipient[] memory _recipients = new Recipient[](2);\\n _recipients[0].recipient = recipient;\\n _recipients[0].bps = creatorSplit;\\n _recipients[1] = commonRecipient;\\n uint256 totalSent;\\n uint256 amountToSend;\\n unchecked {\\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\\n Recipient memory _recipient = _recipients[i];\\n amountToSend = (value * _recipient.bps) / TOTAL_BASIS_POINTS;\\n totalSent += amountToSend;\\n _recipient.recipient.sendValue(amountToSend);\\n emit ETHTransferred(_recipient.recipient, amountToSend);\\n }\\n // Favor the 1st recipient if there are any rounding issues\\n amountToSend = value - totalSent;\\n }\\n _recipients[0].recipient.sendValue(amountToSend);\\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\\n }\\n }\\n\\n /// @notice split ERC20 Tokens owned by this contract.\\n /// @dev can only be called by one of the recipients\\n /// @param erc20Contract the address of the tokens to be split.\\n function splitERC20Tokens(IERC20 erc20Contract) external {\\n require(_splitERC20Tokens(erc20Contract), \\\"Split: ERC20 split failed\\\");\\n }\\n\\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool success) {\\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\\n if (balance == 0) {\\n return false;\\n }\\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\\n require(\\n commonRecipient.recipient == _msgSender() || recipient == _msgSender(),\\n \\\"Split: Can only be called by one of the recipients\\\"\\n );\\n Recipient[] memory _recipients = new Recipient[](2);\\n _recipients[0].recipient = recipient;\\n _recipients[0].bps = creatorSplit;\\n _recipients[1] = commonRecipient;\\n uint256 amountToSend;\\n uint256 totalSent;\\n unchecked {\\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\\n Recipient memory _recipient = _recipients[i];\\n (success, amountToSend) = balance.tryMul(_recipient.bps);\\n require(success, \\\"RoyaltySplitter: Multiplication Overflow\\\");\\n\\n amountToSend /= TOTAL_BASIS_POINTS;\\n totalSent += amountToSend;\\n\\n erc20Contract.safeTransfer(_recipient.recipient, amountToSend);\\n emit ERC20Transferred(address(erc20Contract), _recipient.recipient, amountToSend);\\n }\\n // Favor the 1st recipient if there are any rounding issues\\n amountToSend = balance - totalSent;\\n }\\n erc20Contract.safeTransfer(_recipients[0].recipient, amountToSend);\\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\\n return true;\\n } catch {\\n return false;\\n }\\n }\\n\\n /// @notice verify whether a forwarder address is the trustedForwarder address, using the manager setting\\n /// @dev this function is used to avoid having a trustedForwarder variable inside the splitter\\n /// @return isTrusted bool whether the forwarder is the trusted address\\n function _isTrustedForwarder(address forwarder)\\n internal\\n view\\n override(ERC2771HandlerAbstract)\\n returns (bool isTrusted)\\n {\\n return (forwarder == royaltyManager.getTrustedForwarder());\\n }\\n\\n function _msgSender()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerAbstract)\\n returns (address sender)\\n {\\n return ERC2771HandlerAbstract._msgSender();\\n }\\n\\n function _msgData()\\n internal\\n view\\n virtual\\n override(ContextUpgradeable, ERC2771HandlerAbstract)\\n returns (bytes calldata messageData)\\n {\\n return ERC2771HandlerAbstract._msgData();\\n }\\n}\\n\",\"keccak256\":\"0xa077e9197363476de46c2fa2651b0ed201b20b1b93bde6a0615a2b8e4e380dbc\",\"license\":\"MIT OR Apache-2.0\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n///@title IERC20Approve\\n///@notice Interface for ERC20 token approval operations\\ninterface IERC20Approve {\\n ///@notice Approves the specified spender to spend up to the given amount of tokens on behalf of the sender\\n ///@param spender The address that is allowed to spend tokens\\n ///@param amount The maximum amount of tokens that the spender is allowed to spend\\n ///@return `true` if the approval was successful, otherwise `false`\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n ///@notice Increases the allowance granted to the specified spender by the given amount\\n ///@param spender The address that is allowed to spend tokens\\n ///@param amount The additional amount of tokens that the spender is allowed to spend\\n ///@return `true` if the increase in allowance was successful, otherwise `false`\\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc4e88d5c1caf1a8171d8ee1d82326a4cdf0e05667a61ab4360c71a1b53198f3e\",\"license\":\"MIT\"},\"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {Recipient} from \\\"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\\\";\\n\\n/// @title IRoyaltyManager\\n/// @notice interface for RoyaltyManager Contract\\ninterface IRoyaltyManager {\\n event RecipientSet(address indexed commonRecipient);\\n\\n event SplitSet(uint16 commonSplit);\\n\\n event RoyaltySet(uint16 royaltyBps, address indexed contractAddress);\\n\\n event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder);\\n\\n event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress);\\n\\n ///@notice sets the common recipient\\n ///@param _commonRecipient is the common recipient for all the splitters\\n function setRecipient(address payable _commonRecipient) external;\\n\\n ///@notice sets the common split\\n ///@param commonSplit split for the common recipient\\n function setSplit(uint16 commonSplit) external;\\n\\n ///@notice to be called by the splitters to get the common recipient and split\\n ///@return recipient which has the common recipient and split\\n function getCommonRecipient() external view returns (Recipient memory recipient);\\n\\n ///@notice returns the amount of basis points allocated to the creator\\n ///@return creatorSplit the share of creator in bps\\n function getCreatorSplit() external view returns (uint16 creatorSplit);\\n\\n ///@notice returns the commonRecipient and EIP2981 royalty split\\n ///@return recipient address of common royalty recipient\\n ///@return royaltySplit contract EIP2981 royalty bps\\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit);\\n\\n ///@notice deploys splitter for creator\\n ///@param creator the address of the creator\\n ///@param recipient the wallet of the recipient where they would receive their royalty\\n ///@return creatorSplitterAddress splitter's address deployed for creator\\n function deploySplitter(address creator, address payable recipient)\\n external\\n returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the address of splitter of a creator.\\n ///@param creator the address of the creator\\n ///@return creatorSplitterAddress splitter's address deployed for a creator\\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress);\\n\\n ///@notice returns the EIP2981 royalty split\\n ///@param _contractAddress the address of the contract for which the royalty is required\\n ///@return royaltyBps royalty bps of the contract\\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\\n\\n ///@notice sets the trustedForwarder address to be used by the splitters\\n ///@param _newForwarder is the new trusted forwarder address\\n function setTrustedForwarder(address _newForwarder) external;\\n\\n ///@notice get the current trustedForwarder address\\n ///@return trustedForwarder address of current trusted Forwarder\\n function getTrustedForwarder() external view returns (address trustedForwarder);\\n}\\n\",\"keccak256\":\"0x5e8e149845df288a5d0ddfa00407ebda15d024e8caf1057822670a5232fee93f\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611b74806100ec6000396000f3fe6080604052600436106100cb5760003560e01c80638da5cb5b11610074578063d78d610b1161004e578063d78d610b14610208578063ee295d621461022a578063f2fde38b1461024a57600080fd5b80638da5cb5b146101c2578063c1426d0e146101e0578063d1aa25d01461020057600080fd5b8063572b6c05116100a5578063572b6c051461015557806366d003ac14610175578063715018a6146101ad57600080fd5b806301ffc9a7146100e057806320dc8ff714610115578063485cc9551461013557600080fd5b366100db576100d93461026a565b005b600080fd5b3480156100ec57600080fd5b506101006100fb36600461182a565b610590565b60405190151581526020015b60405180910390f35b34801561012157600080fd5b506100d9610130366004611888565b610629565b34801561014157600080fd5b506100d96101503660046118a5565b610683565b34801561016157600080fd5b50610100610170366004611888565b6107fc565b34801561018157600080fd5b50609754610195906001600160a01b031681565b6040516001600160a01b03909116815260200161010c565b3480156101b957600080fd5b506100d9610807565b3480156101ce57600080fd5b506033546001600160a01b0316610195565b3480156101ec57600080fd5b506100d96101fb3660046118de565b61081b565b6100d96108a8565b34801561021457600080fd5b5061021d6108b1565b60405161010c9190611953565b34801561023657600080fd5b50609854610195906001600160a01b031681565b34801561025657600080fd5b506100d9610265366004611888565b610a72565b801561058d5760985460408051638b49fde760e01b815281516000936001600160a01b031692638b49fde792600480820193918290030181865afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102da91906119c1565b90506000609860009054906101000a90046001600160a01b03166001600160a01b031663706ec2fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610331573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103559190611a2c565b6040805160028082526060820190925291925060009190816020015b604080518082019091526000808252602082015281526020019060019003908161037157505060975481519192506001600160a01b03169082906000906103ba576103ba611a47565b6020026020010151600001906001600160a01b031690816001600160a01b03168152505081816000815181106103f2576103f2611a47565b60200260200101516020019061ffff16908161ffff1681525050828160018151811061042057610420611a47565b60200260200101819052506000806000600184510390505b80156104e657600084828151811061045257610452611a47565b60200260200101519050612710816020015161ffff1689028161047757610477611a5d565b8251919004948501949350610495906001600160a01b031684610aff565b80600001516001600160a01b03167f1445764fe3fdfc2a9812ff42e9b65c2e7896d5162851f78f7d4a5578f7346ff1846040516104d491815260200190565b60405180910390a25060001901610438565b508186039050610526818460008151811061050357610503611a47565b6020026020010151600001516001600160a01b0316610aff90919063ffffffff16565b8260008151811061053957610539611a47565b6020026020010151600001516001600160a01b03167f1445764fe3fdfc2a9812ff42e9b65c2e7896d5162851f78f7d4a5578f7346ff18260405161057f91815260200190565b60405180910390a250505050505b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f16cf0c0500000000000000000000000000000000000000000000000000000000148061062357507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61063281610c18565b61058d5760405162461bcd60e51b815260206004820152601960248201527f53706c69743a2045524332302073706c6974206661696c65640000000000000060448201526064015b60405180910390fd5b600054610100900460ff16158080156106a35750600054600160ff909116105b806106bd5750303b1580156106bd575060005460ff166001145b61072f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610770576000805461ff0019166101001790555b6098805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556107a183611114565b6107a961116b565b6107b16111f0565b80156107f7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006106238261126d565b61080f61130f565b6108196000611388565b565b61082361130f565b600181146108735760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207265636970656e7473206c656e6774680000000000000000604482015260640161067a565b6108a48282600081811061088957610889611a47565b61089f9260206040909202019081019150611888565b611114565b5050565b6108194761026a565b60985460408051638b49fde760e01b815281516060936000936001600160a01b0390911692638b49fde792600480830193928290030181865afa1580156108fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092091906119c1565b90506000609860009054906101000a90046001600160a01b03166001600160a01b031663706ec2fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099b9190611a2c565b60408051600280825260608201909252919250816020015b60408051808201909152600080825260208201528152602001906001900390816109b357505060975481519194506001600160a01b03169084906000906109fc576109fc611a47565b6020026020010151600001906001600160a01b031690816001600160a01b0316815250508083600081518110610a3457610a34611a47565b60200260200101516020019061ffff16908161ffff16815250508183600181518110610a6257610a62611a47565b6020026020010181905250505090565b610a7a61130f565b6001600160a01b038116610af65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161067a565b61058d81611388565b80471015610b4f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161067a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610b9c576040519150601f19603f3d011682016040523d82523d6000602084013e610ba1565b606091505b50509050806107f75760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161067a565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa925050508015610c94575060408051601f3d908101601f19168201909252610c9191810190611a73565b60015b610ca057506000919050565b80600003610cb15750600092915050565b60985460408051638b49fde760e01b815281516000936001600160a01b031692638b49fde792600480820193918290030181865afa158015610cf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1b91906119c1565b90506000609860009054906101000a90046001600160a01b03166001600160a01b031663706ec2fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d969190611a2c565b9050610da06113e7565b6001600160a01b031682600001516001600160a01b03161480610dd85750610dc66113e7565b6097546001600160a01b039081169116145b610e4a5760405162461bcd60e51b815260206004820152603260248201527f53706c69743a2043616e206f6e6c792062652063616c6c6564206279206f6e6560448201527f206f662074686520726563697069656e74730000000000000000000000000000606482015260840161067a565b60408051600280825260608201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081610e6257505060975481519192506001600160a01b0316908290600090610eab57610eab611a47565b6020026020010151600001906001600160a01b031690816001600160a01b0316815250508181600081518110610ee357610ee3611a47565b60200260200101516020019061ffff16908161ffff16815250508281600181518110610f1157610f11611a47565b60200260200101819052506000806000600184510390505b801561105d576000848281518110610f4357610f43611a47565b60200260200101519050610f68816020015161ffff16896113f690919063ffffffff16565b909950935088610fe05760405162461bcd60e51b815260206004820152602860248201527f526f79616c747953706c69747465723a204d756c7469706c69636174696f6e2060448201527f4f766572666c6f77000000000000000000000000000000000000000000000000606482015260840161067a565b80516127109094049392840192611002906001600160a01b038c169086611441565b80600001516001600160a01b03168a6001600160a01b03167fe8de91d538b06154a2c48315768c5046f47e127d7fd3f726fd85cc723f29b0528660405161104b91815260200190565b60405180910390a35060001901610f29565b5080860391506110968360008151811061107957611079611a47565b6020908102919091010151516001600160a01b038a169084611441565b826000815181106110a9576110a9611a47565b6020026020010151600001516001600160a01b0316886001600160a01b03167fe8de91d538b06154a2c48315768c5046f47e127d7fd3f726fd85cc723f29b052846040516110f991815260200190565b60405180910390a3506001979650505050505050565b919050565b6097805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d47940190600090a250565b600054610100900460ff166111e85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067a565b6108196114c1565b600054610100900460ff166108195760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067a565b609854604080517fce1b815f00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163ce1b815f9160048083019260209291908290030181865afa1580156112d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f49190611a8c565b6001600160a01b0316826001600160a01b0316149050919050565b6113176113e7565b6001600160a01b03166113326033546001600160a01b031690565b6001600160a01b0316146108195760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161067a565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006113f161154e565b905090565b6000808360000361140d575060019050600061143a565b8383028385828161142057611420611a5d565b041461143357600080925092505061143a565b6001925090505b9250929050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526107f790849061159b565b600054610100900460ff1661153e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067a565b6108196115496113e7565b611388565b60006115593361126d565b8015611566575060143610155b1561159657507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b60006115f0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116839092919063ffffffff16565b90508051600014806116115750808060200190518101906116119190611aa9565b6107f75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161067a565b6060611692848460008561169a565b949350505050565b6060824710156117125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161067a565b600080866001600160a01b0316858760405161172e9190611aef565b60006040518083038185875af1925050503d806000811461176b576040519150601f19603f3d011682016040523d82523d6000602084013e611770565b606091505b50915091506117818783838761178c565b979650505050505050565b606083156117fb5782516000036117f4576001600160a01b0385163b6117f45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067a565b5081611692565b61169283838151156118105781518083602001fd5b8060405162461bcd60e51b815260040161067a9190611b0b565b60006020828403121561183c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461186c57600080fd5b9392505050565b6001600160a01b038116811461058d57600080fd5b60006020828403121561189a57600080fd5b813561186c81611873565b600080604083850312156118b857600080fd5b82356118c381611873565b915060208301356118d381611873565b809150509250929050565b600080602083850312156118f157600080fd5b823567ffffffffffffffff8082111561190957600080fd5b818501915085601f83011261191d57600080fd5b81358181111561192c57600080fd5b8660208260061b850101111561194157600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b828110156119a257815180516001600160a01b0316855286015161ffff16868501529284019290850190600101611970565b5091979650505050505050565b805161ffff8116811461110f57600080fd5b6000604082840312156119d357600080fd5b6040516040810181811067ffffffffffffffff82111715611a0457634e487b7160e01b600052604160045260246000fd5b6040528251611a1281611873565b8152611a20602084016119af565b60208201529392505050565b600060208284031215611a3e57600080fd5b61186c826119af565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600060208284031215611a8557600080fd5b5051919050565b600060208284031215611a9e57600080fd5b815161186c81611873565b600060208284031215611abb57600080fd5b8151801515811461186c57600080fd5b60005b83811015611ae6578181015183820152602001611ace565b50506000910152565b60008251611b01818460208701611acb565b9190910192915050565b6020815260008251806020840152611b2a816040850160208701611acb565b601f01601f1916919091016040019291505056fea2646970667358221220559f27f072948db4cb7ec0b49ff3a05f06eb32b7389b096d21a0d359945b2e6664736f6c63430008120033", + "deployedBytecode": "0x6080604052600436106100cb5760003560e01c80638da5cb5b11610074578063d78d610b1161004e578063d78d610b14610208578063ee295d621461022a578063f2fde38b1461024a57600080fd5b80638da5cb5b146101c2578063c1426d0e146101e0578063d1aa25d01461020057600080fd5b8063572b6c05116100a5578063572b6c051461015557806366d003ac14610175578063715018a6146101ad57600080fd5b806301ffc9a7146100e057806320dc8ff714610115578063485cc9551461013557600080fd5b366100db576100d93461026a565b005b600080fd5b3480156100ec57600080fd5b506101006100fb36600461182a565b610590565b60405190151581526020015b60405180910390f35b34801561012157600080fd5b506100d9610130366004611888565b610629565b34801561014157600080fd5b506100d96101503660046118a5565b610683565b34801561016157600080fd5b50610100610170366004611888565b6107fc565b34801561018157600080fd5b50609754610195906001600160a01b031681565b6040516001600160a01b03909116815260200161010c565b3480156101b957600080fd5b506100d9610807565b3480156101ce57600080fd5b506033546001600160a01b0316610195565b3480156101ec57600080fd5b506100d96101fb3660046118de565b61081b565b6100d96108a8565b34801561021457600080fd5b5061021d6108b1565b60405161010c9190611953565b34801561023657600080fd5b50609854610195906001600160a01b031681565b34801561025657600080fd5b506100d9610265366004611888565b610a72565b801561058d5760985460408051638b49fde760e01b815281516000936001600160a01b031692638b49fde792600480820193918290030181865afa1580156102b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102da91906119c1565b90506000609860009054906101000a90046001600160a01b03166001600160a01b031663706ec2fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610331573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103559190611a2c565b6040805160028082526060820190925291925060009190816020015b604080518082019091526000808252602082015281526020019060019003908161037157505060975481519192506001600160a01b03169082906000906103ba576103ba611a47565b6020026020010151600001906001600160a01b031690816001600160a01b03168152505081816000815181106103f2576103f2611a47565b60200260200101516020019061ffff16908161ffff1681525050828160018151811061042057610420611a47565b60200260200101819052506000806000600184510390505b80156104e657600084828151811061045257610452611a47565b60200260200101519050612710816020015161ffff1689028161047757610477611a5d565b8251919004948501949350610495906001600160a01b031684610aff565b80600001516001600160a01b03167f1445764fe3fdfc2a9812ff42e9b65c2e7896d5162851f78f7d4a5578f7346ff1846040516104d491815260200190565b60405180910390a25060001901610438565b508186039050610526818460008151811061050357610503611a47565b6020026020010151600001516001600160a01b0316610aff90919063ffffffff16565b8260008151811061053957610539611a47565b6020026020010151600001516001600160a01b03167f1445764fe3fdfc2a9812ff42e9b65c2e7896d5162851f78f7d4a5578f7346ff18260405161057f91815260200190565b60405180910390a250505050505b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f16cf0c0500000000000000000000000000000000000000000000000000000000148061062357507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b61063281610c18565b61058d5760405162461bcd60e51b815260206004820152601960248201527f53706c69743a2045524332302073706c6974206661696c65640000000000000060448201526064015b60405180910390fd5b600054610100900460ff16158080156106a35750600054600160ff909116105b806106bd5750303b1580156106bd575060005460ff166001145b61072f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161067a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610770576000805461ff0019166101001790555b6098805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556107a183611114565b6107a961116b565b6107b16111f0565b80156107f7576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006106238261126d565b61080f61130f565b6108196000611388565b565b61082361130f565b600181146108735760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207265636970656e7473206c656e6774680000000000000000604482015260640161067a565b6108a48282600081811061088957610889611a47565b61089f9260206040909202019081019150611888565b611114565b5050565b6108194761026a565b60985460408051638b49fde760e01b815281516060936000936001600160a01b0390911692638b49fde792600480830193928290030181865afa1580156108fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092091906119c1565b90506000609860009054906101000a90046001600160a01b03166001600160a01b031663706ec2fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099b9190611a2c565b60408051600280825260608201909252919250816020015b60408051808201909152600080825260208201528152602001906001900390816109b357505060975481519194506001600160a01b03169084906000906109fc576109fc611a47565b6020026020010151600001906001600160a01b031690816001600160a01b0316815250508083600081518110610a3457610a34611a47565b60200260200101516020019061ffff16908161ffff16815250508183600181518110610a6257610a62611a47565b6020026020010181905250505090565b610a7a61130f565b6001600160a01b038116610af65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161067a565b61058d81611388565b80471015610b4f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161067a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610b9c576040519150601f19603f3d011682016040523d82523d6000602084013e610ba1565b606091505b50509050806107f75760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161067a565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa925050508015610c94575060408051601f3d908101601f19168201909252610c9191810190611a73565b60015b610ca057506000919050565b80600003610cb15750600092915050565b60985460408051638b49fde760e01b815281516000936001600160a01b031692638b49fde792600480820193918290030181865afa158015610cf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1b91906119c1565b90506000609860009054906101000a90046001600160a01b03166001600160a01b031663706ec2fe6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d969190611a2c565b9050610da06113e7565b6001600160a01b031682600001516001600160a01b03161480610dd85750610dc66113e7565b6097546001600160a01b039081169116145b610e4a5760405162461bcd60e51b815260206004820152603260248201527f53706c69743a2043616e206f6e6c792062652063616c6c6564206279206f6e6560448201527f206f662074686520726563697069656e74730000000000000000000000000000606482015260840161067a565b60408051600280825260608201909252600091816020015b6040805180820190915260008082526020820152815260200190600190039081610e6257505060975481519192506001600160a01b0316908290600090610eab57610eab611a47565b6020026020010151600001906001600160a01b031690816001600160a01b0316815250508181600081518110610ee357610ee3611a47565b60200260200101516020019061ffff16908161ffff16815250508281600181518110610f1157610f11611a47565b60200260200101819052506000806000600184510390505b801561105d576000848281518110610f4357610f43611a47565b60200260200101519050610f68816020015161ffff16896113f690919063ffffffff16565b909950935088610fe05760405162461bcd60e51b815260206004820152602860248201527f526f79616c747953706c69747465723a204d756c7469706c69636174696f6e2060448201527f4f766572666c6f77000000000000000000000000000000000000000000000000606482015260840161067a565b80516127109094049392840192611002906001600160a01b038c169086611441565b80600001516001600160a01b03168a6001600160a01b03167fe8de91d538b06154a2c48315768c5046f47e127d7fd3f726fd85cc723f29b0528660405161104b91815260200190565b60405180910390a35060001901610f29565b5080860391506110968360008151811061107957611079611a47565b6020908102919091010151516001600160a01b038a169084611441565b826000815181106110a9576110a9611a47565b6020026020010151600001516001600160a01b0316886001600160a01b03167fe8de91d538b06154a2c48315768c5046f47e127d7fd3f726fd85cc723f29b052846040516110f991815260200190565b60405180910390a3506001979650505050505050565b919050565b6097805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f9d900d71c28433348acb1bec780a061608a96b149370abce77fd54ba2d47940190600090a250565b600054610100900460ff166111e85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067a565b6108196114c1565b600054610100900460ff166108195760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067a565b609854604080517fce1b815f00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163ce1b815f9160048083019260209291908290030181865afa1580156112d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f49190611a8c565b6001600160a01b0316826001600160a01b0316149050919050565b6113176113e7565b6001600160a01b03166113326033546001600160a01b031690565b6001600160a01b0316146108195760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161067a565b603380546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006113f161154e565b905090565b6000808360000361140d575060019050600061143a565b8383028385828161142057611420611a5d565b041461143357600080925092505061143a565b6001925090505b9250929050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526107f790849061159b565b600054610100900460ff1661153e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161067a565b6108196115496113e7565b611388565b60006115593361126d565b8015611566575060143610155b1561159657507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec36013560601c90565b503390565b60006115f0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166116839092919063ffffffff16565b90508051600014806116115750808060200190518101906116119190611aa9565b6107f75760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161067a565b6060611692848460008561169a565b949350505050565b6060824710156117125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161067a565b600080866001600160a01b0316858760405161172e9190611aef565b60006040518083038185875af1925050503d806000811461176b576040519150601f19603f3d011682016040523d82523d6000602084013e611770565b606091505b50915091506117818783838761178c565b979650505050505050565b606083156117fb5782516000036117f4576001600160a01b0385163b6117f45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161067a565b5081611692565b61169283838151156118105781518083602001fd5b8060405162461bcd60e51b815260040161067a9190611b0b565b60006020828403121561183c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461186c57600080fd5b9392505050565b6001600160a01b038116811461058d57600080fd5b60006020828403121561189a57600080fd5b813561186c81611873565b600080604083850312156118b857600080fd5b82356118c381611873565b915060208301356118d381611873565b809150509250929050565b600080602083850312156118f157600080fd5b823567ffffffffffffffff8082111561190957600080fd5b818501915085601f83011261191d57600080fd5b81358181111561192c57600080fd5b8660208260061b850101111561194157600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b828110156119a257815180516001600160a01b0316855286015161ffff16868501529284019290850190600101611970565b5091979650505050505050565b805161ffff8116811461110f57600080fd5b6000604082840312156119d357600080fd5b6040516040810181811067ffffffffffffffff82111715611a0457634e487b7160e01b600052604160045260246000fd5b6040528251611a1281611873565b8152611a20602084016119af565b60208201529392505050565b600060208284031215611a3e57600080fd5b61186c826119af565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600060208284031215611a8557600080fd5b5051919050565b600060208284031215611a9e57600080fd5b815161186c81611873565b600060208284031215611abb57600080fd5b8151801515811461186c57600080fd5b60005b83811015611ae6578181015183820152602001611ace565b50506000910152565b60008251611b01818460208701611acb565b9190910192915050565b6020815260008251806020840152611b2a816040850160208701611acb565b601f01601f1916919091016040019291505056fea2646970667358221220559f27f072948db4cb7ec0b49ff3a05f06eb32b7389b096d21a0d359945b2e6664736f6c63430008120033", + "devdoc": { + "author": "The Sandbox", + "events": { + "Initialized(uint8)": { + "details": "Triggered when the contract has been initialized or reinitialized." + } + }, + "kind": "dev", + "methods": { + "constructor": { + "custom:oz-upgrades-unsafe-allow": "constructor", + "details": "this protects the implementation contract from behing initialized." + }, + "getRecipients()": { + "returns": { + "recipients": "array of royalty recipients through the splitter and their splits of royalty." + } + }, + "initialize(address,address)": { + "details": "can only be run once.", + "params": { + "_royaltyManager": "the address of the royalty manager contract", + "recipientAddress": "the wallet of the creator when the contract is deployed" + } + }, + "isTrustedForwarder(address)": { + "params": { + "forwarder": "trusted forwarder address to check" + }, + "returns": { + "_0": "true if the address is the same as the trusted forwarder" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setRecipients((address,uint16)[])": { + "details": "only the owner can call this.", + "params": { + "recipients": "the array of recipients which should only have one recipient." + } + }, + "splitERC20Tokens(address)": { + "details": "can only be called by one of the recipients", + "params": { + "erc20Contract": "the address of the tokens to be split." + } + }, + "splitETH()": { + "details": "normally ETH should be split automatically by receive function." + }, + "supportsInterface(bytes4)": { + "params": { + "interfaceId": "the interface identifier, as specified in ERC-165." + }, + "returns": { + "isSupported": "`true` if the contract implements `id`." + } + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "title": "RoyaltySplitter", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "getRecipients()": { + "notice": "to get recipients of royalty through this splitter and their splits of royalty." + }, + "initialize(address,address)": { + "notice": "initialize the contract" + }, + "isTrustedForwarder(address)": { + "notice": "return true if the forwarder is the trusted forwarder" + }, + "setRecipients((address,uint16)[])": { + "notice": "sets recipient for the splitter" + }, + "splitERC20Tokens(address)": { + "notice": "split ERC20 Tokens owned by this contract." + }, + "splitETH()": { + "notice": "Splits and forwards ETH to the royalty receivers" + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements interface `id`." + } + }, + "notice": "RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 686, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 689, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 1219, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 558, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 678, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 1492, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "__gap", + "offset": 0, + "slot": "101", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 4293, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "recipient", + "offset": 0, + "slot": "151", + "type": "t_address_payable" + }, + { + "astId": 4296, + "contract": "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol:RoyaltySplitter", + "label": "royaltyManager", + "offset": 0, + "slot": "152", + "type": "t_contract(IRoyaltyManager)5008" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_address_payable": { + "encoding": "inplace", + "label": "address payable", + "numberOfBytes": "20" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(IRoyaltyManager)5008": { + "encoding": "inplace", + "label": "contract IRoyaltyManager", + "numberOfBytes": "20" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/packages/deploy/deployments/mumbai/solcInputs/101d55502dc3ddda4c84938ce7ac435e.json b/packages/deploy/deployments/mumbai/solcInputs/101d55502dc3ddda4c84938ce7ac435e.json new file mode 100644 index 0000000000..d9d332c0ec --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/101d55502dc3ddda4c84938ce7ac435e.json @@ -0,0 +1,185 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IEIP2981MultiReceiverRoyaltyOverride is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, Recipient[] recipients);\n event DefaultRoyaltySet(uint16 royaltyBPS, Recipient[] recipients);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(TokenRoyaltyConfig[] calldata royalties) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty configuration. Will be used if no token specific configuration is set\n */\n function setDefaultRoyalty(uint16 bps, Recipient[] calldata recipients) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\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/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/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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable,\n IAccessControlUpgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable,\n IERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable,\n IERC1155MetadataURIUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ITokenUtils, IRoyaltyUGC} from \"./interfaces/ITokenUtils.sol\";\n\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771Handler,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor,\n ITokenUtils\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address payable defaultRecipient,\n uint16 defaultBps,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_initialize(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(defaultRecipient, defaultBps, _manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, _defaultRoyaltyBPS, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: ids and metadataHash length mismatch\");\n require(ids.length == amounts.length, \"Asset: ids and amounts length mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], _defaultRoyaltyBPS, payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {\n return hashUsed[metadataHash];\n }\n\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: not allowed to reuse metadata hash\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool)\n {\n return\n id == type(IRoyaltyUGC).interfaceId ||\n id == 0x572b6c05 || // ERC2771\n super.supportsInterface(id);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\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 /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param royaltyBPS should be defult EIP2981 roayaltie.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, royaltyBPS, recipient, creator);\n }\n\n /// @notice sets default royalty bps for EIP2981\n /// @dev only owner can call.\n /// @param defaultBps royalty bps base 10000\n function setDefaultRoyaltyBps(uint16 defaultBps) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setDefaultRoyaltyBps(defaultBps);\n }\n\n /// @notice sets default royalty receiver for EIP2981\n /// @dev only owner can call.\n /// @param defaultReceiver address of default royalty recipient.\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setDefaultRoyaltyReceiver(defaultReceiver);\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771Handler,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_initialize(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `interfaceId`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return\n interfaceId == 0x572b6c05 || // ERC2771\n super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/ERC2771Handler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n/// with an initializer for proxies and a mutable forwarder\n\nabstract contract ERC2771Handler {\n address internal _trustedForwarder;\n\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IRoyaltyUGC} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\";\n\ninterface ITokenUtils is IRoyaltyUGC {\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\n\n function isRevealed(uint256 tokenId) external pure returns (bool);\n\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16);\n\n function getRevealNonce(uint256 tokenId) external pure returns (uint16);\n\n function isBridged(uint256 tokenId) external pure returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyManager} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltySplitter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltySplitter} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\";\n\n/* solhint-disable-next-line no-empty-blocks*/\ncontract MockSplitter is RoyaltySplitter {\n\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IERC20Approve {\n function approve(address spender, uint256 amount) external returns (bool);\n\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyDistributor is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, address recipient);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address recipient);\n\n event RoyaltyRecipientSet(address splitter, address recipient);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty e. Will be used if no token specific configuration is set\n */\n function setDefaultRoyaltyBps(uint16 bps) external;\n\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IRoyaltyUGC {\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\nimport {\n IEIP2981MultiReceiverRoyaltyOverride\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol\";\nimport {IMultiRoyaltyDistributor} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributer\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributer contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to slip its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public _defaultRoyaltyBPS;\n address payable public _defaultRoyaltyReceiver;\n address public royaltyManager;\n\n mapping(uint256 => address payable) public _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n function __MultiRoyaltyDistributor_init(\n address payable defaultRecipient,\n uint16 defaultBps,\n address _royaltyManager\n ) internal {\n _defaultRoyaltyReceiver = defaultRecipient;\n _defaultRoyaltyBPS = defaultBps;\n royaltyManager = _royaltyManager;\n }\n\n /// @notice EIP 165 interface function\n /// @dev used to check the interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IEIP2981MultiReceiverRoyaltyOverride).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param royaltyBPS the bps of for EIP2981 royalty\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) internal {\n require(royaltyBPS < TOTAL_BASIS_POINTS, \"Invalid bps\");\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n _tokenRoyaltiesSplitter[tokenId] = creatorSplitterAddress;\n _tokensWithRoyalties.push(tokenId);\n emit TokenRoyaltySet(tokenId, royaltyBPS, recipient);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty\n /// @param bps the new default royalty in BPS to be set\n function _setDefaultRoyaltyBps(uint16 bps) internal {\n require(bps < TOTAL_BASIS_POINTS, \"Invalid bps\");\n _defaultRoyaltyBPS = bps;\n emit DefaultRoyaltyBpsSet(bps);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty receiver\n /// @param defaultReceiver is the new default royalty receiver in BPS to be set\n function _setDefaultRoyaltyReceiver(address payable defaultReceiver) internal {\n require(defaultReceiver != address(0), \"Default receiver can't be zero\");\n _defaultRoyaltyReceiver = defaultReceiver;\n emit DefaultRoyaltyReceiverSet(defaultReceiver);\n }\n\n /// @notice Returns royalty receivers and their split of royalty for each token\n /// @return royaltyConfigs receivers and their split array as long as the number of tokens.\n function getTokenRoyalties() external view override returns (TokenRoyaltyConfig[] memory royaltyConfigs) {\n royaltyConfigs = new TokenRoyaltyConfig[](_tokensWithRoyalties.length);\n for (uint256 i; i < _tokensWithRoyalties.length; ++i) {\n TokenRoyaltyConfig memory royaltyConfig;\n uint256 tokenId = _tokensWithRoyalties[i];\n address splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n royaltyConfig.recipients = IRoyaltySplitter(splitterAddress).getRecipients();\n }\n royaltyConfig.tokenId = tokenId;\n royaltyConfigs[i] = royaltyConfig;\n }\n }\n\n /// @notice Returns default royalty bps and the default recipient following EIP2981\n /// @dev In this contract there is only one default recipient so its split is 100 percent or 10000 points.\n /// @return bps the royalty percentage in BPS\n /// @return recipients The default recipients with their share of the royalty\n function getDefaultRoyalty() external view override returns (uint16 bps, Recipient[] memory recipients) {\n recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return (_defaultRoyaltyBPS, recipients);\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return address the royalty receiver\n /// @return value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value) public view override returns (address, uint256) {\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return addresses of royalty recipient of the token.\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n Recipient[] memory defaultRecipient = new Recipient[](1);\n defaultRecipient[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return defaultRecipient;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public _creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[msg.sender];\n require(creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(creatorSplitterAddress)._recipient();\n require(_recipient != recipient, \"Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set common recipient to zero address\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n recipient = Recipient({recipient: commonRecipient, bps: commonSplit});\n return recipient;\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress deployed for a creator\n function deploySplitter(address creator, address payable recipient) external returns (address payable) {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n _creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable) {\n return _creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @return commonRecipient\n /// @return royaltySplit\n function getRoyaltyInfo() external view returns (address, uint16) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is Initializable, OwnableUpgradeable, IRoyaltySplitter, ERC165Upgradeable {\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n uint256 internal constant IERC20_APPROVE_SELECTOR =\n 0x095ea7b300000000000000000000000000000000000000000000000000000000;\n uint256 internal constant SELECTOR_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000;\n\n address payable public _recipient;\n IRoyaltyManager public _royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipient the wallet of the creator when the contract is deployed\n /// @param royaltyManager the address of the royalty manager contract.\n function initialize(address payable recipient, address royaltyManager) public initializer {\n __Ownable_init();\n _royaltyManager = IRoyaltyManager(royaltyManager);\n _recipient = recipient;\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n _setRecipients(recipients);\n }\n\n function _setRecipients(Recipient[] calldata recipients) private {\n delete _recipient;\n require(recipients.length == 1, \"Invalid recipents length\");\n _recipient = recipients[0].recipient;\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients of royalty through this splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory recipients = new Recipient[](2);\n recipients[0].recipient = _recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() public {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n amountToSend = (value * recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) public {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n bool success;\n (success, amountToSend) = balance.tryMul(recipient.bps);\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n try erc20Contract.transfer(recipient.recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), recipient.recipient, amountToSend);\n } catch {\n return false;\n }\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n try erc20Contract.transfer(_recipients[0].recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n } catch {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice made for unexpected scenarios when assets are sent to this contact such that they could be recovered.\n /// @dev first attempts to split ERC20 tokens.\n /// @param target target of the call\n /// @param callData for the call.\n function proxyCall(address payable target, bytes calldata callData) external {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n require(\n !callData.startsWith(IERC20Approve.approve.selector) &&\n !callData.startsWith(IERC20Approve.increaseAllowance.selector),\n \"Split: ERC20 tokens must be split\"\n );\n /* solhint-disable-next-line no-empty-blocks*/\n try this.splitERC20Tokens(IERC20(target)) {} catch {}\n target.functionCall(callData);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/2c3b4b6dffad52d9ee7aef38c085eed3.json b/packages/deploy/deployments/mumbai/solcInputs/2c3b4b6dffad52d9ee7aef38c085eed3.json new file mode 100644 index 0000000000..17662abe55 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/2c3b4b6dffad52d9ee7aef38c085eed3.json @@ -0,0 +1,230 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\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/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/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/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/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/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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\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" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable,\n IAccessControlUpgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable,\n IERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable,\n IERC1155MetadataURIUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ITokenUtils, IRoyaltyUGC} from \"./interfaces/ITokenUtils.sol\";\n\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771Handler,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor,\n ITokenUtils\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_initialize(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(_manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: ids and metadataHash length mismatch\");\n require(ids.length == amounts.length, \"Asset: ids and amounts length mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {\n return hashUsed[metadataHash];\n }\n\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: not allowed to reuse metadata hash\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool)\n {\n return\n id == type(IRoyaltyUGC).interfaceId ||\n id == 0x572b6c05 || // ERC2771\n super.supportsInterface(id);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\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 /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, recipient, creator);\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n /// @notice This function is used to register Asset contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Asset: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Asset: registry can't be zero address\");\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is IAssetCreate, Initializable, ERC2771Handler, EIP712Upgradeable, AccessControlUpgradeable {\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_initialize(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param metadataHashes The metadata hashes of the assets to mint\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint,\n /// @param creator The address of the creator\n function createSpecialAsset(\n bytes memory signature,\n uint256 amount,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, 0, amount, metadataHash, true);\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return The catalyst contract address\n function getCatalystContract() external view returns (address) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: signer not set\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771Handler,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_initialize(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `interfaceId`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return\n interfaceId == 0x572b6c05 || // ERC2771\n super.supportsInterface(interfaceId);\n }\n\n /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Catalyst: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Catalyst: registry can't be zero address\");\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/ERC2771Handler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n/// with an initializer for proxies and a mutable forwarder\n\nabstract contract ERC2771Handler {\n address internal _trustedForwarder;\n\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IRoyaltyUGC} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\";\n\ninterface ITokenUtils is IRoyaltyUGC {\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\n\n function isRevealed(uint256 tokenId) external pure returns (bool);\n\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16);\n\n function getRevealNonce(uint256 tokenId) external pure returns (uint16);\n\n function isBridged(uint256 tokenId) external pure returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyManager} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltySplitter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltySplitter} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\";\n\n/* solhint-disable-next-line no-empty-blocks*/\ncontract MockSplitter is RoyaltySplitter {\n\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IERC20Approve {\n function approve(address spender, uint256 amount) external returns (bool);\n\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IMultiRoyaltyRecipients} from \"./IMultiRoyaltyRecipients.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyDistributor is IERC165, IMultiRoyaltyRecipients {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, address recipient);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address recipient);\n\n event RoyaltyRecipientSet(address splitter, address recipient);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyRecipients is IERC165 {\n /**\n * @dev Helper function to get all recipients\n */\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address payable, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IRoyaltyUGC {\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\nimport {IMultiRoyaltyDistributor, IMultiRoyaltyRecipients} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributer\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributer contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to slip its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n address public royaltyManager;\n\n mapping(uint256 => address payable) public _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n function __MultiRoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = _royaltyManager;\n }\n\n /// @notice EIP 165 interface function\n /// @dev used to check the interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n interfaceId == type(IMultiRoyaltyRecipients).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) internal {\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n _tokenRoyaltiesSplitter[tokenId] = creatorSplitterAddress;\n _tokensWithRoyalties.push(tokenId);\n emit TokenRoyaltySet(tokenId, recipient);\n }\n\n /// @notice Returns royalty receivers and their split of royalty for each token\n /// @return royaltyConfigs receivers and their split array as long as the number of tokens.\n function getTokenRoyalties() external view override returns (TokenRoyaltyConfig[] memory royaltyConfigs) {\n royaltyConfigs = new TokenRoyaltyConfig[](_tokensWithRoyalties.length);\n for (uint256 i; i < _tokensWithRoyalties.length; ++i) {\n TokenRoyaltyConfig memory royaltyConfig;\n uint256 tokenId = _tokensWithRoyalties[i];\n address splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n royaltyConfig.recipients = IRoyaltySplitter(splitterAddress).getRecipients();\n }\n royaltyConfig.tokenId = tokenId;\n royaltyConfigs[i] = royaltyConfig;\n }\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return address the royalty receiver\n /// @return value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value) public view override returns (address, uint256) {\n (address payable _defaultRoyaltyReceiver, uint16 _defaultRoyaltyBPS) =\n IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return addresses of royalty recipient of the token.\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n Recipient[] memory defaultRecipient = new Recipient[](1);\n defaultRecipient[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return defaultRecipient;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public _creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[msg.sender];\n require(creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(creatorSplitterAddress)._recipient();\n require(_recipient != recipient, \"Manager: Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set split greater than the total basis point\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n recipient = Recipient({recipient: commonRecipient, bps: commonSplit});\n return recipient;\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress deployed for a creator\n function deploySplitter(address creator, address payable recipient) external returns (address payable) {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n _creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable) {\n return _creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @return commonRecipient\n /// @return royaltySplit\n function getRoyaltyInfo() external view returns (address payable, uint16) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @param _contractAddress the address of the contract for which the royalty is required.\n /// @return royaltyBps royalty bps of the contarct\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) {\n return contractRoyalty[_contractAddress];\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is Initializable, OwnableUpgradeable, IRoyaltySplitter, ERC165Upgradeable {\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n uint256 internal constant IERC20_APPROVE_SELECTOR =\n 0x095ea7b300000000000000000000000000000000000000000000000000000000;\n uint256 internal constant SELECTOR_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000;\n\n address payable public _recipient;\n IRoyaltyManager public _royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipient the wallet of the creator when the contract is deployed\n /// @param royaltyManager the address of the royalty manager contract.\n function initialize(address payable recipient, address royaltyManager) public initializer {\n __Ownable_init();\n _royaltyManager = IRoyaltyManager(royaltyManager);\n _recipient = recipient;\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n _setRecipients(recipients);\n }\n\n function _setRecipients(Recipient[] calldata recipients) private {\n delete _recipient;\n require(recipients.length == 1, \"Invalid recipents length\");\n _recipient = recipients[0].recipient;\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients of royalty through this splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory recipients = new Recipient[](2);\n recipients[0].recipient = _recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() public payable {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n amountToSend = (value * recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) public {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n bool success;\n (success, amountToSend) = balance.tryMul(recipient.bps);\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n try erc20Contract.transfer(recipient.recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), recipient.recipient, amountToSend);\n } catch {\n return false;\n }\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n try erc20Contract.transfer(_recipients[0].recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n } catch {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice made for unexpected scenarios when assets are sent to this contact such that they could be recovered.\n /// @dev first attempts to split ERC20 tokens.\n /// @param target target of the call\n /// @param callData for the call.\n function proxyCall(address payable target, bytes calldata callData) external {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n require(\n !callData.startsWith(IERC20Approve.approve.selector) &&\n !callData.startsWith(IERC20Approve.increaseAllowance.selector),\n \"Split: ERC20 tokens must be split\"\n );\n /* solhint-disable-next-line no-empty-blocks*/\n try this.splitERC20Tokens(IERC20(target)) {} catch {}\n target.functionCall(callData);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/2e27796786b1207e5e1fc2f4aa874073.json b/packages/deploy/deployments/mumbai/solcInputs/2e27796786b1207e5e1fc2f4aa874073.json new file mode 100644 index 0000000000..24af8a4fd4 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/2e27796786b1207e5e1fc2f4aa874073.json @@ -0,0 +1,263 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@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/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@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/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\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/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/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/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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\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" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ITokenUtils, IRoyaltyUGC} from \"./interfaces/ITokenUtils.sol\";\n\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771HandlerUpgradeable,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor,\n ITokenUtils\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_init(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(_manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: ids and metadataHash length mismatch\");\n require(ids.length == amounts.length, \"Asset: ids and amounts length mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {\n return hashUsed[metadataHash];\n }\n\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: not allowed to reuse metadata hash\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool)\n {\n return id == type(IRoyaltyUGC).interfaceId || super.supportsInterface(id);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\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 /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, recipient, creator);\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n /// @notice This function is used to register Asset contract on the Operator Filterer Registry of OpenSea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Asset: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Asset: registry can't be zero address\");\n OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is\n IAssetCreate,\n Initializable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable,\n AccessControlUpgradeable,\n PausableUpgradeable\n{\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n __Pausable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external whenNotPaused {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param metadataHashes The metadata hashes of the assets to mint\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external whenNotPaused {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint,\n /// @param creator The address of the creator\n function createSpecialAsset(\n bytes memory signature,\n uint256 amount,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) whenNotPaused {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, 0, amount, metadataHash, true);\n }\n\n /// @notice Pause the contracts mint and burn functions\n function pause() external onlyRole(PAUSER_ROLE) {\n _pause();\n }\n\n /// @notice Unpause the contracts mint and burn functions\n function unpause() external onlyRole(PAUSER_ROLE) {\n _unpause();\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return The catalyst contract address\n function getCatalystContract() external view returns (address) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetCreate: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {IAssetReveal} from \"./interfaces/IAssetReveal.sol\";\n\n/// @title AssetReveal\n/// @author The Sandbox\n/// @notice Contract for burning and revealing assets\ncontract AssetReveal is\n IAssetReveal,\n Initializable,\n AccessControlUpgradeable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable,\n PausableUpgradeable\n{\n using TokenIdUtils for uint256;\n IAsset private assetContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator to asset id to asset's reveal nonce\n mapping(address => mapping(uint256 => uint16)) internal revealIds;\n\n // mapping for showing whether a revealHash has been used\n // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting\n mapping(bytes32 => bool) internal revealHashesUsed;\n\n // allowance list for tier to be revealed in a single transaction\n mapping(uint8 => bool) internal tierInstantRevealAllowed;\n\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n bytes32 public constant REVEAL_TYPEHASH =\n keccak256(\n \"Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n bytes32 public constant BATCH_REVEAL_TYPEHASH =\n keccak256(\n \"BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)\"\n );\n bytes32 public constant INSTANT_REVEAL_TYPEHASH =\n keccak256(\n \"InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n __Pausable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Reveal an asset to view its abilities and enhancements\n /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId\n /// @param tokenId the tokenId of id idasset to reveal\n /// @param amount the amount of tokens to reveal\n function revealBurn(uint256 tokenId, uint256 amount) external whenNotPaused {\n _burnAsset(tokenId, amount);\n emit AssetRevealBurn(_msgSender(), tokenId, amount);\n }\n\n /// @notice Burn multiple assets to be able to reveal them later\n /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately\n /// @param tokenIds the tokenIds of the assets to burn\n /// @param amounts the amounts of the assets to burn\n function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external whenNotPaused {\n _burnAssetBatch(tokenIds, amounts);\n emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for revealed asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function revealMint(\n bytes memory signature,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external whenNotPaused {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealMint signature\"\n );\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Mint multiple assets with revealed abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenIds The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\n function revealBatchMint(\n bytes calldata signature,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) external whenNotPaused {\n require(prevTokenIds.length == amounts.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid metadataHashes length\");\n require(prevTokenIds.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealBatchMint signature\"\n );\n uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length);\n for (uint256 i = 0; i < prevTokenIds.length; i++) {\n newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]);\n }\n emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction\n /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\n /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param burnAmount The amount of assets to burn\n /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function burnAndReveal(\n bytes memory signature,\n uint256 prevTokenId,\n uint256 burnAmount,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external whenNotPaused {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n uint8 tier = prevTokenId.getTier();\n require(tierInstantRevealAllowed[tier], \"AssetReveal: Tier not allowed for instant reveal\");\n require(\n authValidator.verify(\n signature,\n _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid burnAndReveal signature\"\n );\n _burnAsset(prevTokenId, burnAmount);\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Generate new tokenIds for revealed assets and mint them\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param amounts The array of amounts to mint\n function _revealAsset(\n uint256 prevTokenId,\n string[] calldata metadataHashes,\n uint256[] calldata amounts,\n bytes32[] calldata revealHashes\n ) internal returns (uint256[] memory) {\n uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n require(revealHashesUsed[revealHashes[i]] == false, \"AssetReveal: RevealHash already used\");\n revealHashesUsed[revealHashes[i]] = true;\n }\n if (newTokenIds.length == 1) {\n assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]);\n } else {\n assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes);\n }\n return newTokenIds;\n }\n\n /// @notice Burns an asset to be able to reveal it later\n /// @param tokenId the tokenId of the asset to burn\n /// @param amount the amount of the asset to burn\n function _burnAsset(uint256 tokenId, uint256 amount) internal {\n _verifyBurnData(tokenId, amount);\n assetContract.burnFrom(_msgSender(), tokenId, amount);\n }\n\n function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal {\n require(tokenIds.length == amounts.length, \"AssetReveal: Invalid input\");\n for (uint256 i = 0; i < tokenIds.length; i++) {\n _verifyBurnData(tokenIds[i], amounts[i]);\n }\n assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts);\n }\n\n function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure {\n IAsset.AssetData memory data = tokenId.getData();\n require(!data.revealed, \"AssetReveal: Asset is already revealed\");\n require(amount > 0, \"AssetReveal: Burn amount should be greater than 0\");\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The address of the recipient\n /// @param prevTokenId The unrevealed token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashInstantReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n INSTANT_REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed token\n /// @param prevTokenId The previous token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed tokens\n /// @param prevTokenIds The previous token id\n /// @param amounts The amounts of tokens to mint\n /// @param metadataHashes The arrays of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashBatchReveal(\n address recipient,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n BATCH_REVEAL_TYPEHASH,\n recipient,\n keccak256(abi.encodePacked(prevTokenIds)),\n _encodeBatchAmounts(amounts),\n _encodeBatchHashes(metadataHashes),\n _encodeBatchRevealHashes(revealHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = _encodeHashes(metadataHashes[i]);\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param revealHashes The revealHashes\n /// @return encodedRevealHashes The encoded hashes of the metadata\n function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](revealHashes.length);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i]));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the amounts of the tokens for signature verification\n /// @param amounts The amounts of the tokens\n /// @return encodedAmounts The encoded amounts of the tokens\n function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) {\n bytes32[] memory encodedAmounts = new bytes32[](amounts.length);\n for (uint256 i = 0; i < amounts.length; i++) {\n encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i]));\n }\n return keccak256(abi.encodePacked(encodedAmounts));\n }\n\n /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't\n /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed\n /// @param metadataHashes The hashes of the metadata\n /// @param prevTokenId The previous token id from which the assets are revealed\n /// @return tokenIdArray The array of tokenIds to mint\n function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId)\n internal\n returns (uint256[] memory)\n {\n IAsset.AssetData memory data = prevTokenId.getData();\n require(!data.revealed, \"AssetReveal: already revealed\");\n uint256[] memory tokenIdArray = new uint256[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]);\n if (tokenId == 0) {\n uint16 revealNonce = ++revealIds[data.creator][prevTokenId];\n tokenId = TokenIdUtils.generateTokenId(\n data.creator,\n data.tier,\n data.creatorNonce,\n revealNonce,\n data.bridged\n );\n }\n tokenIdArray[i] = tokenId;\n }\n return tokenIdArray;\n }\n\n /// @notice Get the status of a revealHash\n /// @return Whether it has been used\n function revealHashUsed(bytes32 revealHash) external view returns (bool) {\n return revealHashesUsed[revealHash];\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Set permission for instant reveal for a given tier\n /// @param tier the tier to set the permission for\n /// @param allowed allow or disallow instant reveal for the given tier\n function setTierInstantRevealAllowed(uint8 tier, bool allowed) external onlyRole(DEFAULT_ADMIN_ROLE) {\n tierInstantRevealAllowed[tier] = allowed;\n }\n\n /// @notice Get permission for instant reveal for a given tier\n /// @param tier The tier to check\n /// @return Whether instant reveal is allowed for the given tier\n function getTierInstantRevealAllowed(uint8 tier) external view returns (bool) {\n return tierInstantRevealAllowed[tier];\n }\n\n /// @notice Pause the contracts mint and burn functions\n function pause() external onlyRole(PAUSER_ROLE) {\n _pause();\n }\n\n /// @notice Unpause the contracts mint and burn functions\n function unpause() external onlyRole(PAUSER_ROLE) {\n _unpause();\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: signer not set\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice This contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771HandlerUpgradeable,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) external initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_init(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The IPFS content identifiers for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n emit BaseURISet(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n\n /// @dev Sets `baseURI` as the `_baseURI` for all tokens\n function _setBaseURI(string memory baseURI) internal virtual override {\n super._setBaseURI(baseURI);\n emit BaseURISet(baseURI);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data additional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data additional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `interfaceId`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Catalyst: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Catalyst: registry can't be zero address\");\n OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);\n emit OperatorRegistrySet(registry);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetReveal {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetRevealBurn(address revealer, uint256 unrevealedTokenId, uint256 amount);\n event AssetRevealBatchBurn(address revealer, uint256[] unrevealedTokenIds, uint256[] amounts);\n event AssetRevealMint(\n address recipient,\n uint256 unrevealedTokenId,\n uint256[] amounts,\n uint256[] newTokenIds,\n bytes32[] revealHashes\n );\n event AssetRevealBatchMint(\n address recipient,\n uint256[] unrevealedTokenIds,\n uint256[][] amounts,\n uint256[][] newTokenIds,\n bytes32[][] revealHashes\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n event BaseURISet(string baseURI);\n event OperatorRegistrySet(address indexed registry);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IRoyaltyUGC} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\";\n\ninterface ITokenUtils is IRoyaltyUGC {\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\n\n function isRevealed(uint256 tokenId) external pure returns (bool);\n\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16);\n\n function getRevealNonce(uint256 tokenId) external pure returns (uint16);\n\n function isBridged(uint256 tokenId) external pure returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n _setOperatorFilterRegistry(registry);\n IOperatorFilterRegistry operatorFilterRegistry = _getOperatorFilterRegistry();\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetReveal} from \"../AssetReveal.sol\";\n\ncontract MockAssetReveal is AssetReveal {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n _setOperatorFilterRegistry(registry);\n IOperatorFilterRegistry operatorFilterRegistry = _getOperatorFilterRegistry();\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockOperatorFilterRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyManager} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltySplitter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltySplitter} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\";\n\n/* solhint-disable-next-line no-empty-blocks*/\ncontract MockSplitter is RoyaltySplitter {\n\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\nabstract contract ERC2771HandlerAbstract {\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function isTrustedForwarder(address forwarder) external view returns (bool) {\n return _isTrustedForwarder(forwarder);\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual returns (address sender) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n sender = msg.sender;\n }\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual returns (bytes calldata) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n /// @dev this function must be IMPLEMENTED\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC2771HandlerAbstract} from \"./ERC2771HandlerAbstract.sol\";\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\n address private _trustedForwarder;\n\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\n /// @param oldTrustedForwarder old trusted forwarder\n /// @param newTrustedForwarder new trusted forwarder\n /// @param operator the sender of the transaction\n event TrustedForwarderSet(\n address indexed oldTrustedForwarder,\n address indexed newTrustedForwarder,\n address indexed operator\n );\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\n __ERC2771Handler_init_unchained(forwarder);\n }\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\n _setTrustedForwarder(forwarder);\n }\n\n /// @notice return the address of the trusted forwarder\n /// @return return the address of the trusted forwarder\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n /// @notice set the address of the trusted forwarder\n /// @param newForwarder the address of the new forwarder.\n function _setTrustedForwarder(address newForwarder) internal virtual {\n require(newForwarder != _trustedForwarder, \"ERC2771HandlerUpgradeable: forwarder already set\");\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\n _trustedForwarder = newForwarder;\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual override returns (address sender) {\n return super._msgSender();\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual override returns (bytes calldata) {\n return super._msgData();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IOperatorFilterRegistry\n/// @notice Interface for managing operators and filtering.\ninterface IOperatorFilterRegistry {\n ///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n /// true if supplied registrant address is not registered.\n function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed);\n\n ///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n function register(address registrant) external;\n\n ///@notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n function registerAndSubscribe(address registrant, address subscription) external;\n\n ///@notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n /// address without subscribing.\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n ///@notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n /// Note that this does not remove any filtered addresses or codeHashes.\n /// Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n function unregister(address addr) external;\n\n ///@notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n ///@notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n ///@notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n ///@notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n ///@notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n /// subscription if present.\n /// Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n /// subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n /// used.\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n ///@notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n ///@notice Get the subscription address of a given registrant, if any.\n function subscriptionOf(address addr) external returns (address registrant);\n\n ///@notice Get the set of addresses subscribed to a given registrant.\n /// Note that order is not guaranteed as updates are made.\n function subscribers(address registrant) external returns (address[] memory subscribersList);\n\n ///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n /// Note that order is not guaranteed as updates are made.\n function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress);\n\n ///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n ///@notice Returns true if operator is filtered by a given address or its subscription.\n function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered);\n\n ///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered);\n\n ///@notice Returns true if a codeHash is filtered by a given address or its subscription.\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered);\n\n ///@notice Returns a list of filtered operators for a given address or its subscription.\n function filteredOperators(address addr) external returns (address[] memory operatorList);\n\n ///@notice Returns the set of filtered codeHashes for a given address or its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList);\n\n ///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n /// its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredOperatorAt(address registrant, uint256 index) external returns (address operator);\n\n ///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n /// its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash);\n\n ///@notice Returns true if an address has registered\n function isRegistered(address addr) external returns (bool registered);\n\n ///@dev Convenience method to compute the code hash of an arbitrary contract\n function codeHashOf(address addr) external returns (bytes32 codeHash);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"operator-filter-registry/src/IOperatorFilterRegistry.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n OperatorFilterRegistryErrorsAndEvents\n} from \"operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol\";\n\n/**\n * @title MockOperatorFilterRegistry\n * @notice Made based on the OperatorFilterRegistry of OpenSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol\n * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be\n * * restricted according to the isOperatorAllowed function.\n */\ncontract MockOperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)\n /// Note that this will also be a smart contract's codehash when making calls from its constructor.\n bytes32 internal constant EOA_CODEHASH = keccak256(\"\");\n\n mapping(address => EnumerableSet.AddressSet) private _filteredOperators;\n mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;\n mapping(address => address) private _registrations;\n mapping(address => EnumerableSet.AddressSet) private _subscribers;\n\n constructor(address _defaultSubscription, address[] memory _blacklistedAddresses) {\n _registrations[_defaultSubscription] = _defaultSubscription;\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[_defaultSubscription];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[_defaultSubscription];\n for (uint256 i; i < _blacklistedAddresses.length; i++) {\n filteredOperatorsRef.add(_blacklistedAddresses[i]);\n bytes32 codeHash = _blacklistedAddresses[i].codehash;\n filteredCodeHashesRef.add(codeHash);\n }\n }\n\n /**\n * @notice Restricts method caller to the address or EIP-173 \"owner()\"\n */\n modifier onlyAddressOrOwner(address addr) {\n if (msg.sender != addr) {\n try Ownable(addr).owner() returns (address owner) {\n if (msg.sender != owner) {\n revert OnlyAddressOrOwner();\n }\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NotOwnable();\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n }\n _;\n }\n\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n * Note that this method will *revert* if an operator or its codehash is filtered with an error that is\n * more informational than a false boolean, so smart contracts that query this method for informational\n * purposes will need to wrap in a try/catch or perform a low-level staticcall in order to handle the case\n * that an operator is filtered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n EnumerableSet.AddressSet storage filteredOperatorsRef;\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef;\n\n filteredOperatorsRef = _filteredOperators[registration];\n filteredCodeHashesRef = _filteredCodeHashes[registration];\n\n if (filteredOperatorsRef.contains(operator)) {\n revert AddressFiltered(operator);\n }\n if (operator.code.length > 0) {\n bytes32 codeHash = operator.codehash;\n if (filteredCodeHashesRef.contains(codeHash)) {\n revert CodeHashFiltered(operator, codeHash);\n }\n }\n }\n return true;\n }\n\n //////////////////\n // AUTH METHODS //\n //////////////////\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external onlyAddressOrOwner(registrant) {\n if (_registrations[registrant] != address(0)) {\n revert AlreadyRegistered();\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n }\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address registrant) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = address(0);\n emit RegistrationUpdated(registrant, false);\n }\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n if (registrant == subscription) {\n revert CannotSubscribeToSelf();\n }\n address subscriptionRegistration = _registrations[subscription];\n if (subscriptionRegistration == address(0)) {\n revert NotRegistered(subscription);\n }\n if (subscriptionRegistration != subscription) {\n revert CannotSubscribeToRegistrantWithSubscription(subscription);\n }\n\n _registrations[registrant] = subscription;\n _subscribers[subscription].add(registrant);\n emit RegistrationUpdated(registrant, true);\n emit SubscriptionUpdated(registrant, subscription, true);\n }\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy)\n external\n onlyAddressOrOwner(registrant)\n {\n if (registrantToCopy == registrant) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n _copyEntries(registrant, registrantToCopy);\n }\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n\n if (!filtered) {\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n } else {\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n }\n emit OperatorUpdated(registrant, operator, filtered);\n }\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codeHash,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n\n if (!filtered) {\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n } else {\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n }\n emit CodeHashUpdated(registrant, codeHash, filtered);\n }\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n uint256 operatorsLength = operators.length;\n if (!filtered) {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n unchecked {++i;}\n }\n }\n emit OperatorsUpdated(registrant, operators, filtered);\n }\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n uint256 codeHashesLength = codeHashes.length;\n if (!filtered) {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n unchecked {++i;}\n }\n }\n emit CodeHashesUpdated(registrant, codeHashes, filtered);\n }\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {\n if (registrant == newSubscription) {\n revert CannotSubscribeToSelf();\n }\n if (newSubscription == address(0)) {\n revert CannotSubscribeToZeroAddress();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == newSubscription) {\n revert AlreadySubscribed(newSubscription);\n }\n address newSubscriptionRegistration = _registrations[newSubscription];\n if (newSubscriptionRegistration == address(0)) {\n revert NotRegistered(newSubscription);\n }\n if (newSubscriptionRegistration != newSubscription) {\n revert CannotSubscribeToRegistrantWithSubscription(newSubscription);\n }\n\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = newSubscription;\n _subscribers[newSubscription].add(registrant);\n emit SubscriptionUpdated(registrant, newSubscription, true);\n }\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == registrant) {\n revert NotSubscribed();\n }\n _subscribers[registration].remove(registrant);\n _registrations[registrant] = registrant;\n emit SubscriptionUpdated(registrant, registration, false);\n if (copyExistingEntries) {\n _copyEntries(registrant, registration);\n }\n }\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {\n if (registrant == registrantToCopy) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _copyEntries(registrant, registrantToCopy);\n }\n\n /// @dev helper to copy entries from registrantToCopy to registrant and emit events\n function _copyEntries(address registrant, address registrantToCopy) private {\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];\n uint256 filteredOperatorsLength = filteredOperatorsRef.length();\n uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();\n for (uint256 i = 0; i < filteredOperatorsLength; ) {\n address operator = filteredOperatorsRef.at(i);\n bool added = _filteredOperators[registrant].add(operator);\n if (added) {\n emit OperatorUpdated(registrant, operator, true);\n }\n unchecked {++i;}\n }\n for (uint256 i = 0; i < filteredCodeHashesLength; ) {\n bytes32 codehash = filteredCodeHashesRef.at(i);\n bool added = _filteredCodeHashes[registrant].add(codehash);\n if (added) {\n emit CodeHashUpdated(registrant, codehash, true);\n }\n unchecked {++i;}\n }\n }\n\n //////////////////\n // VIEW METHODS //\n //////////////////\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address registrant) external view returns (address subscription) {\n subscription = _registrations[registrant];\n if (subscription == address(0)) {\n revert NotRegistered(registrant);\n } else if (subscription == registrant) {\n subscription = address(0);\n }\n }\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external view returns (address[] memory) {\n return _subscribers[registrant].values();\n }\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external view returns (address) {\n return _subscribers[registrant].at(index);\n }\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].contains(operator);\n }\n return _filteredOperators[registrant].contains(operator);\n }\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {\n bytes32 codeHash = operatorWithCode.codehash;\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address registrant) external view returns (bool) {\n return _registrations[registrant] != address(0);\n }\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address registrant) external view returns (address[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].values();\n }\n return _filteredOperators[registrant].values();\n }\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].values();\n }\n return _filteredCodeHashes[registrant].values();\n }\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].at(index);\n }\n return _filteredOperators[registrant].at(index);\n }\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].at(index);\n }\n return _filteredCodeHashes[registrant].at(index);\n }\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address a) external view returns (bytes32) {\n return a.codehash;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The Sandbox\n///@notice This contract would subscribe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's address could be set using a setter which could be implemented in inheriting contract\nabstract contract OperatorFiltererUpgradeable is Initializable, ContextUpgradeable {\n event OperatorFilterRegistrySet(address indexed registry);\n\n IOperatorFilterRegistry private operatorFilterRegistry;\n\n // solhint-disable-next-line func-name-mixedcase\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == _msgSender()) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), _msgSender())) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n /// @notice returns the operator filter registry.\n /// @return operatorFilterRegistryAddress address of operator filter registry contract.\n function getOperatorFilterRegistry() external view returns (IOperatorFilterRegistry operatorFilterRegistryAddress) {\n return _getOperatorFilterRegistry();\n }\n\n /// @notice internal method to set the operator filter registry\n /// @param registry address the registry.\n function _setOperatorFilterRegistry(address registry) internal {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n emit OperatorFilterRegistrySet(registry);\n }\n\n /// @notice internal method to get the operator filter registry.\n function _getOperatorFilterRegistry()\n internal\n view\n returns (IOperatorFilterRegistry operatorFilterRegistryAddress)\n {\n return operatorFilterRegistry;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n///@title IERC20Approve\n///@notice Interface for ERC20 token approval operations\ninterface IERC20Approve {\n ///@notice Approves the specified spender to spend up to the given amount of tokens on behalf of the sender\n ///@param spender The address that is allowed to spend tokens\n ///@param amount The maximum amount of tokens that the spender is allowed to spend\n ///@return `true` if the approval was successful, otherwise `false`\n function approve(address spender, uint256 amount) external returns (bool);\n\n ///@notice Increases the allowance granted to the specified spender by the given amount\n ///@param spender The address that is allowed to spend tokens\n ///@param amount The additional amount of tokens that the spender is allowed to spend\n ///@return `true` if the increase in allowance was successful, otherwise `false`\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IMultiRoyaltyRecipients} from \"./IMultiRoyaltyRecipients.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n///Multi-receiver EIP2981 reference override implementation\ninterface IMultiRoyaltyDistributor is IERC165, IMultiRoyaltyRecipients {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address indexed recipient);\n\n event RoyaltyRecipientSet(address indexed splitter, address indexed recipient);\n\n event TokenRoyaltySplitterSet(uint256 tokenId, address splitterAddress);\n\n event RoyaltyManagerSet(address indexed _royaltyManager);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n ///@notice Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n ///@param tokenId The ID of the token for which to set the royalties.\n ///@param recipient The address that will receive the royalties.\n ///@param creator The creator's address for the token.\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external;\n\n ///@notice Helper function to get all splits contracts\n ///@return an array of royalty receiver\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/// Multi-receiver EIP2981 implementation\ninterface IMultiRoyaltyRecipients is IERC165 {\n /// @dev Helper function to get all recipients\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/// @title IRoyaltyManager\n/// @notice interface for RoyaltyManager Contract\ninterface IRoyaltyManager {\n event RecipientSet(address indexed commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address indexed contractAddress);\n\n event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder);\n\n event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress);\n\n ///@notice sets the common recipient\n ///@param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external;\n\n ///@notice sets the common split\n ///@param commonSplit split for the common recipient\n function setSplit(uint16 commonSplit) external;\n\n ///@notice to be called by the splitters to get the common recipient and split\n ///@return recipient which has the common recipient and split\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n ///@notice returns the amount of basis points allocated to the creator\n ///@return creatorSplit the share of creator in bps\n function getCreatorSplit() external view returns (uint16 creatorSplit);\n\n ///@notice returns the commonRecipient and EIP2981 royalty split\n ///@return recipient address of common royalty recipient\n ///@return royaltySplit contract EIP2981 royalty bps\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit);\n\n ///@notice deploys splitter for creator\n ///@param creator the address of the creator\n ///@param recipient the wallet of the recipient where they would receive their royalty\n ///@return creatorSplitterAddress splitter's address deployed for creator\n function deploySplitter(address creator, address payable recipient)\n external\n returns (address payable creatorSplitterAddress);\n\n ///@notice returns the address of splitter of a creator.\n ///@param creator the address of the creator\n ///@return creatorSplitterAddress splitter's address deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress);\n\n ///@notice returns the EIP2981 royalty split\n ///@param _contractAddress the address of the contract for which the royalty is required\n ///@return royaltyBps royalty bps of the contract\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\n\n ///@notice sets the trustedForwarder address to be used by the splitters\n ///@param _newForwarder is the new trusted forwarder address\n function setTrustedForwarder(address _newForwarder) external;\n\n ///@notice get the current trustedForwarder address\n ///@return trustedForwarder address of current trusted Forwarder\n function getTrustedForwarder() external view returns (address trustedForwarder);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IRoyaltyUGC\n/// @notice interface define function for managing creator of UGC (User-Generated Content)\ninterface IRoyaltyUGC {\n ///@notice Gets the address of the creator associated with a specific token.\n ///@param tokenId the Id of token to retrieve the creator address for\n ///@return creator the address of creator\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {IMultiRoyaltyDistributor, IMultiRoyaltyRecipients} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributor\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributor contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to split its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n address private royaltyManager;\n\n mapping(uint256 => address payable) private _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n // solhint-disable-next-line func-name-mixedcase\n function __MultiRoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing {\n _setRoyaltyManager(_royaltyManager);\n __ERC165_init_unchained();\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return isSupported `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool isSupported)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n interfaceId == type(IMultiRoyaltyRecipients).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param recipient royalty recipient\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) internal {\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n if (_tokenRoyaltiesSplitter[tokenId] != creatorSplitterAddress) {\n _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress);\n }\n } else {\n _tokensWithRoyalties.push(tokenId);\n _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress);\n }\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return receiver address the royalty receiver\n /// @return royaltyAmount value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value)\n public\n view\n override\n returns (address receiver, uint256 royaltyAmount)\n {\n (address payable _defaultRoyaltyReceiver, uint16 _defaultRoyaltyBPS) =\n IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return recipients array of royalty recipients for the token\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory recipients) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n recipients = new Recipient[](1);\n recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return recipients;\n }\n\n /// @notice internal function to set the token royalty splitter\n /// @param tokenId id of token\n /// @param splitterAddress address of the splitter contract\n function _setTokenRoyaltiesSplitter(uint256 tokenId, address payable splitterAddress) internal {\n _tokenRoyaltiesSplitter[tokenId] = splitterAddress;\n emit TokenRoyaltySplitterSet(tokenId, splitterAddress);\n }\n\n /// @notice returns the address of token royalty splitter.\n /// @param tokenId is the token id for which royalty splitter should be returned.\n /// @return splitterAddress address of royalty splitter for the token\n function getTokenRoyaltiesSplitter(uint256 tokenId) external view returns (address payable splitterAddress) {\n return _tokenRoyaltiesSplitter[tokenId];\n }\n\n /// @notice returns the address of royalty manager.\n /// @return managerAddress address of royalty manager.\n function getRoyaltyManager() external view returns (address managerAddress) {\n return royaltyManager;\n }\n\n /// @notice set royalty manager address\n /// @param _royaltyManager address of royalty manager to set\n function _setRoyaltyManager(address _royaltyManager) internal {\n royaltyManager = _royaltyManager;\n emit RoyaltyManagerSet(_royaltyManager);\n }\n\n uint256[47] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n ERC165Upgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title RoyaltyDistributor\n/// @author The Sandbox\n/// @notice Contract for distributing royalties based on the ERC2981 standard.\nabstract contract RoyaltyDistributor is IERC2981Upgradeable, ERC165Upgradeable {\n event RoyaltyManagerSet(address indexed _royaltyManager);\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager private royaltyManager;\n\n // solhint-disable-next-line func-name-mixedcase\n function __RoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing {\n _setRoyaltyManager(_royaltyManager);\n __ERC165_init_unchained();\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return isSupported `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool isSupported)\n {\n return (interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId));\n }\n\n /// @notice returns the royalty manager\n /// @return royaltyManagerAddress address of royalty manager contract.\n function getRoyaltyManager() external view returns (IRoyaltyManager royaltyManagerAddress) {\n return royaltyManager;\n }\n\n /// @notice set royalty manager\n /// @param _royaltyManager address of royalty manager to set\n function _setRoyaltyManager(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n emit RoyaltyManagerSet(_royaltyManager);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER_ROLE\");\n bytes32 public constant SPLITTER_DEPLOYER_ROLE = keccak256(\"SPLITTER_DEPLOYER_ROLE\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n address internal _trustedForwarder;\n\n /// @dev this protects the implementation contract from behing initialized.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n /// @param trustedForwarder the trustedForwarder address for royalty splitters to use.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter,\n address trustedForwarder\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable _creatorSplitterAddress = creatorRoyaltiesSplitter[msg.sender];\n require(_creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(_creatorSplitterAddress).recipient();\n require(_recipient != recipient, \"Manager: Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(_creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient\n /// @dev can only be called by the admin\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the trustedForwarder address to be used by the splitters\n /// @dev can only be called by the admin\n /// new splitters will read this value\n /// @param _newForwarder is the new trusted forwarder address\n function setTrustedForwarder(address _newForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTrustedForwarder(_newForwarder);\n }\n\n /// @notice sets the common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n /// @notice get the current trustedForwarder address\n /// @return trustedForwarder address of current TrustedForwarder\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set split greater than the total basis point\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice sets trusted forwarder address\n /// @param _newForwarder new trusted forwarder address to set\n function _setTrustedForwarder(address _newForwarder) internal {\n address oldTrustedForwarder = _trustedForwarder;\n _trustedForwarder = _newForwarder;\n emit TrustedForwarderSet(oldTrustedForwarder, _newForwarder);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param contractAddress address of contract for which royalty is set\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n return Recipient({recipient: commonRecipient, bps: commonSplit});\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress splitter's address deployed for a creator\n function deploySplitter(address creator, address payable recipient)\n external\n onlyRole(SPLITTER_DEPLOYER_ROLE)\n returns (address payable creatorSplitterAddress)\n {\n creatorSplitterAddress = creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n emit SplitterDeployed(creator, recipient, creatorSplitterAddress);\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress splitter's address deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress) {\n return creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice returns the amount of basis points allocated to the creator\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16 creatorSplit) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty bps\n /// @return recipient address of common royalty recipient\n /// @return royaltySplit contract EIP2981 royalty bps\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n\n /// @notice returns the EIP2981 royalty bps\n /// @param _contractAddress the address of the contract for which the royalty is required\n /// @return royaltyBps royalty bps of the contract\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) {\n return contractRoyalty[_contractAddress];\n }\n\n uint256[44] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OwnableUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {ERC2771HandlerAbstract} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is\n Initializable,\n OwnableUpgradeable,\n IRoyaltySplitter,\n ERC165Upgradeable,\n ERC2771HandlerAbstract\n{\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n\n address payable public recipient;\n IRoyaltyManager public royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n event RecipientSet(address indexed recipientAddress);\n\n /// @dev this protects the implementation contract from behing initialized.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return isSupported `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool isSupported)\n {\n return (interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId));\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipientAddress the wallet of the creator when the contract is deployed\n /// @param _royaltyManager the address of the royalty manager contract\n function initialize(address payable recipientAddress, address _royaltyManager) external initializer {\n royaltyManager = IRoyaltyManager(_royaltyManager); // set manager before Ownable_init for _isTrustedForwarder\n _setRecipient(recipientAddress);\n __Ownable_init();\n __ERC165_init();\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n require(recipients.length == 1, \"Invalid recipents length\");\n _setRecipient(recipients[0].recipient);\n }\n\n function _setRecipient(address payable recipientAddress) private {\n recipient = recipientAddress;\n emit RecipientSet(recipientAddress);\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients array of royalty recipients through the splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory recipients) {\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\n recipients = new Recipient[](2);\n recipients[0].recipient = recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() external payable {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory _recipient = _recipients[i];\n amountToSend = (value * _recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n _recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) external {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool success) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == _msgSender() || recipient == _msgSender(),\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory _recipient = _recipients[i];\n (success, amountToSend) = balance.tryMul(_recipient.bps);\n require(success, \"RoyaltySplitter: Multiplication Overflow\");\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n\n erc20Contract.safeTransfer(_recipient.recipient, amountToSend);\n emit ERC20Transferred(address(erc20Contract), _recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n erc20Contract.safeTransfer(_recipients[0].recipient, amountToSend);\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice verify whether a forwarder address is the trustedForwarder address, using the manager setting\n /// @dev this function is used to avoid having a trustedForwarder variable inside the splitter\n /// @return isTrusted bool whether the forwarder is the trusted address\n function _isTrustedForwarder(address forwarder)\n internal\n view\n override(ERC2771HandlerAbstract)\n returns (bool isTrusted)\n {\n return (forwarder == royaltyManager.getTrustedForwarder());\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata messageData)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + }, + "operator-filter-registry/src/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(address registrant, address operator, bool filtered) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(address registrant, address[] calldata operators, bool filtered) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ncontract OperatorFilterRegistryErrorsAndEvents {\n /// @notice Emitted when trying to register an address that has no code.\n error CannotFilterEOAs();\n\n /// @notice Emitted when trying to add an address that is already filtered.\n error AddressAlreadyFiltered(address operator);\n\n /// @notice Emitted when trying to remove an address that is not filtered.\n error AddressNotFiltered(address operator);\n\n /// @notice Emitted when trying to add a codehash that is already filtered.\n error CodeHashAlreadyFiltered(bytes32 codeHash);\n\n /// @notice Emitted when trying to remove a codehash that is not filtered.\n error CodeHashNotFiltered(bytes32 codeHash);\n\n /// @notice Emitted when the caller is not the address or EIP-173 \"owner()\"\n error OnlyAddressOrOwner();\n\n /// @notice Emitted when the registrant is not registered.\n error NotRegistered(address registrant);\n\n /// @notice Emitted when the registrant is already registered.\n error AlreadyRegistered();\n\n /// @notice Emitted when the registrant is already subscribed.\n error AlreadySubscribed(address subscription);\n\n /// @notice Emitted when the registrant is not subscribed.\n error NotSubscribed();\n\n /// @notice Emitted when trying to update a registration where the registrant is already subscribed.\n error CannotUpdateWhileSubscribed(address subscription);\n\n /// @notice Emitted when trying to subscribe to itself.\n error CannotSubscribeToSelf();\n\n /// @notice Emitted when trying to subscribe to the zero address.\n error CannotSubscribeToZeroAddress();\n\n /// @notice Emitted when trying to register and the contract is not ownable (EIP-173 \"owner()\")\n error NotOwnable();\n\n /// @notice Emitted when an address is filtered.\n error AddressFiltered(address filtered);\n\n /// @notice Emitted when a codeHash is filtered.\n error CodeHashFiltered(address account, bytes32 codeHash);\n\n /// @notice Emited when trying to register to a registrant with a subscription.\n error CannotSubscribeToRegistrantWithSubscription(address registrant);\n\n /// @notice Emitted when trying to copy a registration from itself.\n error CannotCopyFromSelf();\n\n /// @notice Emitted when a registration is updated.\n event RegistrationUpdated(address indexed registrant, bool indexed registered);\n\n /// @notice Emitted when an operator is updated.\n event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);\n\n /// @notice Emitted when multiple operators are updated.\n event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);\n\n /// @notice Emitted when a codeHash is updated.\n event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);\n\n /// @notice Emitted when multiple codeHashes are updated.\n event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);\n\n /// @notice Emitted when a subscription is updated.\n event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/2e616d6ee49dab0a55f9d72f1f7a9977.json b/packages/deploy/deployments/mumbai/solcInputs/2e616d6ee49dab0a55f9d72f1f7a9977.json new file mode 100644 index 0000000000..c0f4c0a918 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/2e616d6ee49dab0a55f9d72f1f7a9977.json @@ -0,0 +1,203 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IEIP2981MultiReceiverRoyaltyOverride is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, Recipient[] recipients);\n event DefaultRoyaltySet(uint16 royaltyBPS, Recipient[] recipients);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(TokenRoyaltyConfig[] calldata royalties) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty configuration. Will be used if no token specific configuration is set\n */\n function setDefaultRoyalty(uint16 bps, Recipient[] calldata recipients) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\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/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/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/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/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/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" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable,\n IAccessControlUpgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable,\n IERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable,\n IERC1155MetadataURIUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ITokenUtils, IRoyaltyUGC} from \"./interfaces/ITokenUtils.sol\";\n\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771Handler,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor,\n ITokenUtils\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address payable defaultRecipient,\n uint16 defaultBps,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_initialize(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(defaultRecipient, defaultBps, _manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, _defaultRoyaltyBPS, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: ids and metadataHash length mismatch\");\n require(ids.length == amounts.length, \"Asset: ids and amounts length mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], _defaultRoyaltyBPS, payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {\n return hashUsed[metadataHash];\n }\n\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: not allowed to reuse metadata hash\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool)\n {\n return\n id == type(IERC165Upgradeable).interfaceId ||\n id == type(IERC1155Upgradeable).interfaceId ||\n id == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n id == type(IAccessControlUpgradeable).interfaceId ||\n id == type(IRoyaltyUGC).interfaceId ||\n id == 0x572b6c05; // ERC2771\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\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 /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param royaltyBPS should be defult EIP2981 roayaltie.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, royaltyBPS, recipient, creator);\n }\n\n /// @notice sets default royalty bps for EIP2981\n /// @dev only owner can call.\n /// @param defaultBps royalty bps base 10000\n function setDefaultRoyaltyBps(uint16 defaultBps) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setDefaultRoyaltyBps(defaultBps);\n }\n\n /// @notice sets default royalty receiver for EIP2981\n /// @dev only owner can call.\n /// @param defaultReceiver address of default royalty recipient.\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setDefaultRoyaltyReceiver(defaultReceiver);\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is IAssetCreate, Initializable, ERC2771Handler, EIP712Upgradeable, AccessControlUpgradeable {\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_initialize(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param metadataHashes The metadata hashes of the assets to mint\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createSpecialAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return The catalyst contract address\n function getCatalystContract() external view returns (address) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {IAssetReveal} from \"./interfaces/IAssetReveal.sol\";\n\n/// @title AssetReveal\n/// @author The Sandbox\n/// @notice Contract for burning and revealing assets\ncontract AssetReveal is IAssetReveal, Initializable, AccessControlUpgradeable, ERC2771Handler, EIP712Upgradeable {\n using TokenIdUtils for uint256;\n IAsset private assetContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator to asset id to asset's reveal nonce\n mapping(address => mapping(uint256 => uint16)) internal revealIds;\n\n // mapping for showing whether a revealHash has been used\n // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting\n mapping(bytes32 => bool) internal revealHashesUsed;\n\n bytes32 public constant REVEAL_TYPEHASH =\n keccak256(\n \"Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n bytes32 public constant BATCH_REVEAL_TYPEHASH =\n keccak256(\n \"BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)\"\n );\n bytes32 public constant INSTANT_REVEAL_TYPEHASH =\n keccak256(\n \"InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_initialize(_forwarder);\n __EIP712_init(_name, _version);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Reveal an asset to view its abilities and enhancements\n /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId\n /// @param tokenId the tokenId of id idasset to reveal\n /// @param amount the amount of tokens to reveal\n function revealBurn(uint256 tokenId, uint256 amount) external {\n _burnAsset(tokenId, amount);\n emit AssetRevealBurn(_msgSender(), tokenId, amount);\n }\n\n /// @notice Burn multiple assets to be able to reveal them later\n /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately\n /// @param tokenIds the tokenIds of the assets to burn\n /// @param amounts the amounts of the assets to burn\n function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external {\n _burnAssetBatch(tokenIds, amounts);\n emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for revealed asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function revealMint(\n bytes memory signature,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealMint signature\"\n );\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Mint multiple assets with revealed abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenIds The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\n function revealBatchMint(\n bytes calldata signature,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) external {\n require(prevTokenIds.length == amounts.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid metadataHashes length\");\n require(prevTokenIds.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealBatchMint signature\"\n );\n uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length);\n for (uint256 i = 0; i < prevTokenIds.length; i++) {\n newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]);\n }\n emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction\n /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\n /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param burnAmount The amount of assets to burn\n /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function burnAndReveal(\n bytes memory signature,\n uint256 prevTokenId,\n uint256 burnAmount,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid burnAndReveal signature\"\n );\n _burnAsset(prevTokenId, burnAmount);\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Generate new tokenIds for revealed assets and mint them\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param amounts The array of amounts to mint\n function _revealAsset(\n uint256 prevTokenId,\n string[] calldata metadataHashes,\n uint256[] calldata amounts,\n bytes32[] calldata revealHashes\n ) internal returns (uint256[] memory) {\n uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n require(revealHashesUsed[revealHashes[i]] == false, \"AssetReveal: RevealHash already used\");\n revealHashesUsed[revealHashes[i]] = true;\n }\n if (newTokenIds.length == 1) {\n assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]);\n } else {\n assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes);\n }\n return newTokenIds;\n }\n\n /// @notice Burns an asset to be able to reveal it later\n /// @param tokenId the tokenId of the asset to burn\n /// @param amount the amount of the asset to burn\n function _burnAsset(uint256 tokenId, uint256 amount) internal {\n _verifyBurnData(tokenId, amount);\n assetContract.burnFrom(_msgSender(), tokenId, amount);\n }\n\n function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal {\n require(tokenIds.length == amounts.length, \"AssetReveal: Invalid input\");\n for (uint256 i = 0; i < tokenIds.length; i++) {\n _verifyBurnData(tokenIds[i], amounts[i]);\n }\n assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts);\n }\n\n function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure {\n IAsset.AssetData memory data = tokenId.getData();\n require(!data.revealed, \"AssetReveal: Asset is already revealed\");\n require(amount > 0, \"AssetReveal: Burn amount should be greater than 0\");\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The address of the recipient\n /// @param prevTokenId The unrevealed token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashInstantReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n INSTANT_REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed token\n /// @param prevTokenId The previous token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed tokens\n /// @param prevTokenIds The previous token id\n /// @param amounts The amounts of tokens to mint\n /// @param metadataHashes The arrays of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashBatchReveal(\n address recipient,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n BATCH_REVEAL_TYPEHASH,\n recipient,\n keccak256(abi.encodePacked(prevTokenIds)),\n _encodeBatchAmounts(amounts),\n _encodeBatchHashes(metadataHashes),\n _encodeBatchRevealHashes(revealHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = _encodeHashes(metadataHashes[i]);\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param revealHashes The revealHashes\n /// @return encodedRevealHashes The encoded hashes of the metadata\n function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](revealHashes.length);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i]));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the amounts of the tokens for signature verification\n /// @param amounts The amounts of the tokens\n /// @return encodedAmounts The encoded amounts of the tokens\n function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) {\n bytes32[] memory encodedAmounts = new bytes32[](amounts.length);\n for (uint256 i = 0; i < amounts.length; i++) {\n encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i]));\n }\n return keccak256(abi.encodePacked(encodedAmounts));\n }\n\n /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't\n /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed\n /// @param metadataHashes The hashes of the metadata\n /// @param prevTokenId The previous token id from which the assets are revealed\n /// @return tokenIdArray The array of tokenIds to mint\n function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId)\n internal\n returns (uint256[] memory)\n {\n IAsset.AssetData memory data = prevTokenId.getData();\n require(!data.revealed, \"AssetReveal: already revealed\");\n uint256[] memory tokenIdArray = new uint256[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]);\n if (tokenId == 0) {\n uint16 revealNonce = ++revealIds[data.creator][prevTokenId];\n tokenId = TokenIdUtils.generateTokenId(\n data.creator,\n data.tier,\n data.creatorNonce,\n revealNonce,\n data.bridged\n );\n }\n tokenIdArray[i] = tokenId;\n }\n return tokenIdArray;\n }\n\n /// @notice Get the status of a revealHash\n /// @return Whether it has been used\n function revealHashUsed(bytes32 revealHash) external view returns (bool) {\n return revealHashesUsed[revealHash];\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: signer not set\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/ERC2771Handler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n/// with an initializer for proxies and a mutable forwarder\n\nabstract contract ERC2771Handler {\n address internal _trustedForwarder;\n\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetReveal {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetRevealBurn(address revealer, uint256 unrevealedTokenId, uint256 amount);\n event AssetRevealBatchBurn(address revealer, uint256[] unrevealedTokenIds, uint256[] amounts);\n event AssetRevealMint(\n address recipient,\n uint256 unrevealedTokenId,\n uint256[] amounts,\n uint256[] newTokenIds,\n bytes32[] revealHashes\n );\n event AssetRevealBatchMint(\n address recipient,\n uint256[] unrevealedTokenIds,\n uint256[][] amounts,\n uint256[][] newTokenIds,\n bytes32[][] revealHashes\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param catalystId The catalyst id to add\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(uint256 catalystId, string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IRoyaltyUGC} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\";\n\ninterface ITokenUtils is IRoyaltyUGC {\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\n\n function isRevealed(uint256 tokenId) external pure returns (bool);\n\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16);\n\n function getRevealNonce(uint256 tokenId) external pure returns (uint16);\n\n function isBridged(uint256 tokenId) external pure returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetReveal} from \"../AssetReveal.sol\";\n\ncontract MockAssetReveal is AssetReveal {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMinter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\nimport {TokenIdUtils} from \"../libraries/TokenIdUtils.sol\";\n\ncontract MockMinter {\n using TokenIdUtils for uint256;\n\n IAsset public assetContract;\n\n mapping(address => uint16) public creatorNonces;\n\n event Minted(uint256 tokenId, uint256 amount);\n\n constructor(address _assetContract) {\n assetContract = IAsset(_assetContract);\n }\n\n /// @dev Mints a specified number of unrevealed copies of specific tier\n function mintAsset(\n address recipient,\n uint256 amount,\n uint8 tier,\n bool revealed,\n string calldata metadataHash\n ) public {\n // increment nonce\n unchecked {creatorNonces[msg.sender]++;}\n // get current creator nonce\n uint16 creatorNonce = creatorNonces[msg.sender];\n uint256 tokenId = TokenIdUtils.generateTokenId(msg.sender, tier, creatorNonce, revealed ? 1 : 0, false);\n\n assetContract.mint(recipient, tokenId, amount, metadataHash);\n emit Minted(tokenId, amount);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/TokenIdUtilsWrapped.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {TokenIdUtils} from \"../libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\ncontract TokenIdUtilsWrapped {\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) public pure returns (uint256 tokenId) {\n return TokenIdUtils.generateTokenId(creator, tier, creatorNonce, revealNonce, bridged);\n }\n\n function getCreatorAddress(uint256 tokenId) public pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n function getTier(uint256 tokenId) public pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n function getCreatorNonce(uint256 tokenId) public pure returns (uint16 creatorNonce) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n function isRevealed(uint256 tokenId) public pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n function getRevealNonce(uint256 tokenId) public pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n function isBridged(uint256 tokenId) public pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n function getData(uint256 tokenId) public pure returns (IAsset.AssetData memory data) {\n return TokenIdUtils.getData(tokenId);\n }\n\n function TIER_MASK() public pure returns (uint256) {\n return TokenIdUtils.TIER_MASK;\n }\n\n function NONCE_MASK() public pure returns (uint256) {\n return TokenIdUtils.NONCE_MASK;\n }\n\n function REVEAL_NONCE_MASK() public pure returns (uint256) {\n return TokenIdUtils.REVEAL_NONCE_MASK;\n }\n\n function BRIDGED_MASK() public pure returns (uint256) {\n return TokenIdUtils.BRIDGED_MASK;\n }\n\n function TIER_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.TIER_SHIFT;\n }\n\n function NONCE_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.NONCE_SHIFT;\n }\n\n function REVEAL_NONCE_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.REVEAL_NONCE_SHIFT;\n }\n\n function BRIDGED_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.BRIDGED_SHIFT;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyDistributor is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, address recipient);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address recipient);\n\n event RoyaltyRecipientSet(address splitter, address recipient);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty e. Will be used if no token specific configuration is set\n */\n function setDefaultRoyaltyBps(uint16 bps) external;\n\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IRoyaltyUGC {\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\nimport {\n IEIP2981MultiReceiverRoyaltyOverride\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol\";\nimport {IMultiRoyaltyDistributor} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributer\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributer contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to slip its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public _defaultRoyaltyBPS;\n address payable public _defaultRoyaltyReceiver;\n address public royaltyManager;\n\n mapping(uint256 => address payable) public _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n function __MultiRoyaltyDistributor_init(\n address payable defaultRecipient,\n uint16 defaultBps,\n address _royaltyManager\n ) internal {\n _defaultRoyaltyReceiver = defaultRecipient;\n _defaultRoyaltyBPS = defaultBps;\n royaltyManager = _royaltyManager;\n }\n\n /// @notice EIP 165 interface function\n /// @dev used to check the interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IEIP2981MultiReceiverRoyaltyOverride).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param royaltyBPS the bps of for EIP2981 royalty\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) internal {\n require(royaltyBPS < TOTAL_BASIS_POINTS, \"Invalid bps\");\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n _tokenRoyaltiesSplitter[tokenId] = creatorSplitterAddress;\n _tokensWithRoyalties.push(tokenId);\n emit TokenRoyaltySet(tokenId, royaltyBPS, recipient);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty\n /// @param bps the new default royalty in BPS to be set\n function _setDefaultRoyaltyBps(uint16 bps) internal {\n require(bps < TOTAL_BASIS_POINTS, \"Invalid bps\");\n _defaultRoyaltyBPS = bps;\n emit DefaultRoyaltyBpsSet(bps);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty receiver\n /// @param defaultReceiver is the new default royalty receiver in BPS to be set\n function _setDefaultRoyaltyReceiver(address payable defaultReceiver) internal {\n require(defaultReceiver != address(0), \"Default receiver can't be zero\");\n _defaultRoyaltyReceiver = defaultReceiver;\n emit DefaultRoyaltyReceiverSet(defaultReceiver);\n }\n\n /// @notice Returns royalty receivers and their split of royalty for each token\n /// @return royaltyConfigs receivers and their split array as long as the number of tokens.\n function getTokenRoyalties() external view override returns (TokenRoyaltyConfig[] memory royaltyConfigs) {\n royaltyConfigs = new TokenRoyaltyConfig[](_tokensWithRoyalties.length);\n for (uint256 i; i < _tokensWithRoyalties.length; ++i) {\n TokenRoyaltyConfig memory royaltyConfig;\n uint256 tokenId = _tokensWithRoyalties[i];\n address splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n royaltyConfig.recipients = IRoyaltySplitter(splitterAddress).getRecipients();\n }\n royaltyConfig.tokenId = tokenId;\n royaltyConfigs[i] = royaltyConfig;\n }\n }\n\n /// @notice Returns default royalty bps and the default recipient following EIP2981\n /// @dev In this contract there is only one default recipient so its split is 100 percent or 10000 points.\n /// @return bps the royalty percentage in BPS\n /// @return recipients The default recipients with their share of the royalty\n function getDefaultRoyalty() external view override returns (uint16 bps, Recipient[] memory recipients) {\n recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return (_defaultRoyaltyBPS, recipients);\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return address the royalty receiver\n /// @return value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value) public view override returns (address, uint256) {\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return addresses of royalty recipient of the token.\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n Recipient[] memory defaultRecipient = new Recipient[](1);\n defaultRecipient[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return defaultRecipient;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/467ad2aa755667473a7c4622090bf333.json b/packages/deploy/deployments/mumbai/solcInputs/467ad2aa755667473a7c4622090bf333.json new file mode 100644 index 0000000000..488c8c323c --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/467ad2aa755667473a7c4622090bf333.json @@ -0,0 +1,110 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@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/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n /**\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n */\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 oldAllowance = token.allowance(address(this), spender);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful.\n */\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n }\n }\n\n /**\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n * to be set to zero before setting it to a non-zero value, such as USDT.\n */\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\n bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n *\n * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n */\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n // and not revert is the subcall reverts.\n\n (bool success, bytes memory returndata) = address(token).call(data);\n return\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\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/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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\nabstract contract ERC2771HandlerAbstract {\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function isTrustedForwarder(address forwarder) external view returns (bool) {\n return _isTrustedForwarder(forwarder);\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual returns (address sender) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n sender = msg.sender;\n }\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual returns (bytes calldata) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n /// @dev this function must be IMPLEMENTED\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n///@title IERC20Approve\n///@notice Interface for ERC20 token approval operations\ninterface IERC20Approve {\n ///@notice Approves the specified spender to spend up to the given amount of tokens on behalf of the sender\n ///@param spender The address that is allowed to spend tokens\n ///@param amount The maximum amount of tokens that the spender is allowed to spend\n ///@return `true` if the approval was successful, otherwise `false`\n function approve(address spender, uint256 amount) external returns (bool);\n\n ///@notice Increases the allowance granted to the specified spender by the given amount\n ///@param spender The address that is allowed to spend tokens\n ///@param amount The additional amount of tokens that the spender is allowed to spend\n ///@return `true` if the increase in allowance was successful, otherwise `false`\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/// @title IRoyaltyManager\n/// @notice interface for RoyaltyManager Contract\ninterface IRoyaltyManager {\n event RecipientSet(address indexed commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address indexed contractAddress);\n\n event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder);\n\n event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress);\n\n ///@notice sets the common recipient\n ///@param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external;\n\n ///@notice sets the common split\n ///@param commonSplit split for the common recipient\n function setSplit(uint16 commonSplit) external;\n\n ///@notice to be called by the splitters to get the common recipient and split\n ///@return recipient which has the common recipient and split\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n ///@notice returns the amount of basis points allocated to the creator\n ///@return creatorSplit the share of creator in bps\n function getCreatorSplit() external view returns (uint16 creatorSplit);\n\n ///@notice returns the commonRecipient and EIP2981 royalty split\n ///@return recipient address of common royalty recipient\n ///@return royaltySplit contract EIP2981 royalty bps\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit);\n\n ///@notice deploys splitter for creator\n ///@param creator the address of the creator\n ///@param recipient the wallet of the recipient where they would receive their royalty\n ///@return creatorSplitterAddress splitter's address deployed for creator\n function deploySplitter(address creator, address payable recipient)\n external\n returns (address payable creatorSplitterAddress);\n\n ///@notice returns the address of splitter of a creator.\n ///@param creator the address of the creator\n ///@return creatorSplitterAddress splitter's address deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress);\n\n ///@notice returns the EIP2981 royalty split\n ///@param _contractAddress the address of the contract for which the royalty is required\n ///@return royaltyBps royalty bps of the contract\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\n\n ///@notice sets the trustedForwarder address to be used by the splitters\n ///@param _newForwarder is the new trusted forwarder address\n function setTrustedForwarder(address _newForwarder) external;\n\n ///@notice get the current trustedForwarder address\n ///@return trustedForwarder address of current trusted Forwarder\n function getTrustedForwarder() external view returns (address trustedForwarder);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/OverflowERC20.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\ncontract OverflowTestERC20 {\n uint256 constant MAX_BALANCE = 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n mapping(address => uint256) private balances;\n\n function mintMax(address account) external {\n balances[account] = MAX_BALANCE;\n }\n\n function balanceOf(address _account) external view returns (uint256) {\n return balances[_account];\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER_ROLE\");\n bytes32 public constant SPLITTER_DEPLOYER_ROLE = keccak256(\"SPLITTER_DEPLOYER_ROLE\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n address internal _trustedForwarder;\n\n /// @dev this protects the implementation contract from behing initialized.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n /// @param trustedForwarder the trustedForwarder address for royalty splitters to use.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter,\n address trustedForwarder\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable _creatorSplitterAddress = creatorRoyaltiesSplitter[msg.sender];\n require(_creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(_creatorSplitterAddress).recipient();\n require(_recipient != recipient, \"Manager: Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(_creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient\n /// @dev can only be called by the admin\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the trustedForwarder address to be used by the splitters\n /// @dev can only be called by the admin\n /// new splitters will read this value\n /// @param _newForwarder is the new trusted forwarder address\n function setTrustedForwarder(address _newForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTrustedForwarder(_newForwarder);\n }\n\n /// @notice sets the common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n /// @notice get the current trustedForwarder address\n /// @return trustedForwarder address of current TrustedForwarder\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set split greater than the total basis point\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice sets trusted forwarder address\n /// @param _newForwarder new trusted forwarder address to set\n function _setTrustedForwarder(address _newForwarder) internal {\n address oldTrustedForwarder = _trustedForwarder;\n _trustedForwarder = _newForwarder;\n emit TrustedForwarderSet(oldTrustedForwarder, _newForwarder);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param contractAddress address of contract for which royalty is set\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n return Recipient({recipient: commonRecipient, bps: commonSplit});\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress splitter's address deployed for a creator\n function deploySplitter(address creator, address payable recipient)\n external\n onlyRole(SPLITTER_DEPLOYER_ROLE)\n returns (address payable creatorSplitterAddress)\n {\n creatorSplitterAddress = creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n emit SplitterDeployed(creator, recipient, creatorSplitterAddress);\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress splitter's address deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress) {\n return creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice returns the amount of basis points allocated to the creator\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16 creatorSplit) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty bps\n /// @return recipient address of common royalty recipient\n /// @return royaltySplit contract EIP2981 royalty bps\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n\n /// @notice returns the EIP2981 royalty bps\n /// @param _contractAddress the address of the contract for which the royalty is required\n /// @return royaltyBps royalty bps of the contract\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) {\n return contractRoyalty[_contractAddress];\n }\n\n uint256[44] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OwnableUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {ERC2771HandlerAbstract} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is\n Initializable,\n OwnableUpgradeable,\n IRoyaltySplitter,\n ERC165Upgradeable,\n ERC2771HandlerAbstract\n{\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n\n address payable public recipient;\n IRoyaltyManager public royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n event RecipientSet(address indexed recipientAddress);\n\n /// @dev this protects the implementation contract from behing initialized.\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return isSupported `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool isSupported)\n {\n return (interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId));\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipientAddress the wallet of the creator when the contract is deployed\n /// @param _royaltyManager the address of the royalty manager contract\n function initialize(address payable recipientAddress, address _royaltyManager) external initializer {\n royaltyManager = IRoyaltyManager(_royaltyManager); // set manager before Ownable_init for _isTrustedForwarder\n _setRecipient(recipientAddress);\n __Ownable_init();\n __ERC165_init();\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n require(recipients.length == 1, \"Invalid recipents length\");\n _setRecipient(recipients[0].recipient);\n }\n\n function _setRecipient(address payable recipientAddress) private {\n recipient = recipientAddress;\n emit RecipientSet(recipientAddress);\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients array of royalty recipients through the splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory recipients) {\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\n recipients = new Recipient[](2);\n recipients[0].recipient = recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() external payable {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory _recipient = _recipients[i];\n amountToSend = (value * _recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n _recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) external {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool success) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = royaltyManager.getCommonRecipient();\n uint16 creatorSplit = royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == _msgSender() || recipient == _msgSender(),\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory _recipient = _recipients[i];\n (success, amountToSend) = balance.tryMul(_recipient.bps);\n require(success, \"RoyaltySplitter: Multiplication Overflow\");\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n\n erc20Contract.safeTransfer(_recipient.recipient, amountToSend);\n emit ERC20Transferred(address(erc20Contract), _recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n erc20Contract.safeTransfer(_recipients[0].recipient, amountToSend);\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice verify whether a forwarder address is the trustedForwarder address, using the manager setting\n /// @dev this function is used to avoid having a trustedForwarder variable inside the splitter\n /// @return isTrusted bool whether the forwarder is the trusted address\n function _isTrustedForwarder(address forwarder)\n internal\n view\n override(ERC2771HandlerAbstract)\n returns (bool isTrusted)\n {\n return (forwarder == royaltyManager.getTrustedForwarder());\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata messageData)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/6f473f7e77d584cdbb9fe0c91f28e82a.json b/packages/deploy/deployments/mumbai/solcInputs/6f473f7e77d584cdbb9fe0c91f28e82a.json new file mode 100644 index 0000000000..3862116d29 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/6f473f7e77d584cdbb9fe0c91f28e82a.json @@ -0,0 +1,425 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/libraries-solidity/contracts/access/IAdminControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface for admin control\n */\ninterface IAdminControl is IERC165 {\n\n event AdminApproved(address indexed account, address indexed sender);\n event AdminRevoked(address indexed account, address indexed sender);\n\n /**\n * @dev gets address of all admins\n */\n function getAdmins() external view returns (address[] memory);\n\n /**\n * @dev add an admin. Can only be called by contract owner.\n */\n function approveAdmin(address admin) external;\n\n /**\n * @dev remove an admin. Can only be called by contract owner.\n */\n function revokeAdmin(address admin) external;\n\n /**\n * @dev checks whether or not given address is an admin\n * Returns True if they are\n */\n function isAdmin(address admin) external view returns (bool);\n\n}" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/FallbackRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport { Recipient } from \"./overrides/IRoyaltySplitter.sol\";\nimport { Ownable2Step } from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport { IFallbackRegistry } from \"./overrides/IFallbackRegistry.sol\";\n\ncontract FallbackRegistry is IFallbackRegistry, Ownable2Step {\n struct TokenFallback {\n address tokenAddress;\n Recipient[] recipients;\n }\n\n mapping(address => Recipient[]) fallbacks;\n\n constructor(address initialOwner) {\n _transferOwnership(initialOwner);\n }\n\n function setFallback(address tokenAddress, Recipient[] calldata _recipients) public onlyOwner {\n Recipient[] storage recipients = fallbacks[tokenAddress];\n uint256 recipientsLength = _recipients.length;\n ///@solidity memory-safe-assembly\n assembly {\n // overwrite length directly rather than deleting and then updating it each time we push new values\n // this means if the new array is shorter than the old ones, those slots will stay dirty, but they\n // should not be able to be accessed due to the new length\n sstore(recipients.slot, recipientsLength)\n }\n for (uint256 i; i < recipientsLength;) {\n recipients[i] = _recipients[i];\n unchecked {\n ++i;\n }\n }\n }\n\n function setFallbacks(TokenFallback[] calldata bundle) external onlyOwner {\n uint256 bundleLength = bundle.length;\n for (uint256 i = 0; i < bundleLength;) {\n TokenFallback calldata tokenFallback = bundle[i];\n setFallback(tokenFallback.tokenAddress, tokenFallback.recipients);\n unchecked {\n ++i;\n }\n }\n }\n\n function getRecipients(address tokenAddress) external view returns (Recipient[] memory) {\n return fallbacks[tokenAddress];\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyEngineV1.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Lookup engine interface\n */\ninterface IRoyaltyEngineV1 is IERC165 {\n /**\n * Get the royalty for a given token (address, id) and value amount. Does not cache the bps/amounts. Caches the spec for a given token address\n *\n * @param tokenAddress - The address of the token\n * @param tokenId - The id of the token\n * @param value - The value you wish to get the royalty of\n *\n * returns Two arrays of equal length, royalty recipients and the corresponding amount each recipient should get\n */\n function getRoyalty(address tokenAddress, uint256 tokenId, uint256 value)\n external\n returns (address payable[] memory recipients, uint256[] memory amounts);\n\n /**\n * View only version of getRoyalty\n *\n * @param tokenAddress - The address of the token\n * @param tokenId - The id of the token\n * @param value - The value you wish to get the royalty of\n *\n * returns Two arrays of equal length, royalty recipients and the corresponding amount each recipient should get\n */\n function getRoyaltyView(address tokenAddress, uint256 tokenId, uint256 value)\n external\n view\n returns (address payable[] memory recipients, uint256[] memory amounts);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Royalty registry interface\n */\ninterface IRoyaltyRegistry is IERC165 {\n event RoyaltyOverride(address owner, address tokenAddress, address royaltyAddress);\n\n /**\n * Override the location of where to look up royalty information for a given token contract.\n * Allows for backwards compatibility and implementation of royalty logic for contracts that did not previously support them.\n *\n * @param tokenAddress - The token address you wish to override\n * @param royaltyAddress - The royalty override address\n */\n function setRoyaltyLookupAddress(address tokenAddress, address royaltyAddress) external returns (bool);\n\n /**\n * Returns royalty address location. Returns the tokenAddress by default, or the override if it exists\n *\n * @param tokenAddress - The token address you are looking up the royalty for\n */\n function getRoyaltyLookupAddress(address tokenAddress) external view returns (address);\n\n /**\n * Returns the token address that an overrideAddress is set for.\n * Note: will not be accurate if the override was created before this function was added.\n *\n * @param overrideAddress - The override address you are looking up the token for\n */\n function getOverrideLookupTokenAddress(address overrideAddress) external view returns (address);\n\n /**\n * Whether or not the message sender can override the royalty address for the given token address\n *\n * @param tokenAddress - The token address you are looking up the royalty for\n */\n function overrideAllowed(address tokenAddress) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/SuperRareContracts.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary SuperRareContracts {\n address public constant SUPERRARE_REGISTRY = 0x17B0C8564E53f22364A6C8de6F7ca5CE9BEa4e5D;\n address public constant SUPERRARE_V1 = 0x41A322b28D0fF354040e2CbC676F0320d8c8850d;\n address public constant SUPERRARE_V2 = 0xb932a70A57673d89f4acfFBE830E8ed7f75Fb9e0;\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IFallbackRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport { Recipient } from \"./IRoyaltySplitter.sol\";\n\ninterface IFallbackRegistry {\n /**\n * @dev Get total recipients for token fees. Note that recipient bps is of gross amount, not share of fee amount,\n * ie, recipients' BPS will not sum to 10_000, but to the total fee BPS for an order.\n */\n function getRecipients(address tokenAddress) external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyEngineV1.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport { ERC165, IERC165 } from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { AddressUpgradeable } from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport { SuperRareContracts } from \"./libraries/SuperRareContracts.sol\";\n\nimport { IManifold } from \"./specs/IManifold.sol\";\nimport { IRaribleV1, IRaribleV2 } from \"./specs/IRarible.sol\";\nimport { IFoundation } from \"./specs/IFoundation.sol\";\nimport { ISuperRareRegistry } from \"./specs/ISuperRare.sol\";\nimport { IEIP2981 } from \"./specs/IEIP2981.sol\";\nimport { IZoraOverride } from \"./specs/IZoraOverride.sol\";\nimport { IArtBlocksOverride } from \"./specs/IArtBlocksOverride.sol\";\nimport { IKODAV2Override } from \"./specs/IKODAV2Override.sol\";\nimport { IRoyaltyEngineV1 } from \"./IRoyaltyEngineV1.sol\";\nimport { IRoyaltyRegistry } from \"./IRoyaltyRegistry.sol\";\nimport { IRoyaltySplitter, Recipient } from \"./overrides/IRoyaltySplitter.sol\";\nimport { IFallbackRegistry } from \"./overrides/IFallbackRegistry.sol\";\n/**\n * @dev Engine to lookup royalty configurations\n */\n\ncontract RoyaltyEngineV1 is ERC165, OwnableUpgradeable, IRoyaltyEngineV1 {\n using AddressUpgradeable for address;\n\n // Use int16 for specs to support future spec additions\n // When we add a spec, we also decrement the NONE value\n // Anything > NONE and <= NOT_CONFIGURED is considered not configured\n int16 private constant NONE = -1;\n int16 private constant NOT_CONFIGURED = 0;\n int16 private constant MANIFOLD = 1;\n int16 private constant RARIBLEV1 = 2;\n int16 private constant RARIBLEV2 = 3;\n int16 private constant FOUNDATION = 4;\n int16 private constant EIP2981 = 5;\n int16 private constant SUPERRARE = 6;\n int16 private constant ZORA = 7;\n int16 private constant ARTBLOCKS = 8;\n int16 private constant KNOWNORIGINV2 = 9;\n int16 private constant ROYALTY_SPLITTER = 10;\n int16 private constant FALLBACK = type(int16).max;\n\n mapping(address => int16) _specCache;\n\n address public royaltyRegistry;\n IFallbackRegistry public immutable FALLBACK_REGISTRY;\n\n constructor(address fallbackRegistry) {\n FALLBACK_REGISTRY = IFallbackRegistry(fallbackRegistry);\n }\n\n function initialize(address _initialOwner, address royaltyRegistry_) public initializer {\n _transferOwnership(_initialOwner);\n require(ERC165Checker.supportsInterface(royaltyRegistry_, type(IRoyaltyRegistry).interfaceId));\n royaltyRegistry = royaltyRegistry_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override (ERC165, IERC165) returns (bool) {\n return interfaceId == type(IRoyaltyEngineV1).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Invalidate the cached spec (useful for situations where tooken royalty implementation changes to a different spec)\n */\n function invalidateCachedRoyaltySpec(address tokenAddress) public {\n address royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n delete _specCache[royaltyAddress];\n }\n\n /**\n * @dev View function to get the cached spec of a token\n */\n function getCachedRoyaltySpec(address tokenAddress) public view returns (int16) {\n address royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n return _specCache[royaltyAddress];\n }\n\n /**\n * @dev See {IRoyaltyEngineV1-getRoyalty}\n */\n function getRoyalty(address tokenAddress, uint256 tokenId, uint256 value)\n public\n override\n returns (address payable[] memory recipients, uint256[] memory amounts)\n {\n // External call to limit gas\n try this._getRoyaltyAndSpec{gas: 100000}(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients,\n uint256[] memory _amounts,\n int16 spec,\n address royaltyAddress,\n bool addToCache\n ) {\n if (addToCache) _specCache[royaltyAddress] = spec;\n return (_recipients, _amounts);\n } catch {\n revert(\"Invalid royalty amount\");\n }\n }\n\n /**\n * @dev See {IRoyaltyEngineV1-getRoyaltyView}.\n */\n function getRoyaltyView(address tokenAddress, uint256 tokenId, uint256 value)\n public\n view\n override\n returns (address payable[] memory recipients, uint256[] memory amounts)\n {\n // External call to limit gas\n try this._getRoyaltyAndSpec{gas: 100000}(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients, uint256[] memory _amounts, int16, address, bool\n ) {\n return (_recipients, _amounts);\n } catch {\n revert(\"Invalid royalty amount\");\n }\n }\n\n /**\n * @dev Get the royalty and royalty spec for a given token\n *\n * returns recipients array, amounts array, royalty spec, royalty address, whether or not to add to cache\n */\n function _getRoyaltyAndSpec(address tokenAddress, uint256 tokenId, uint256 value)\n external\n view\n returns (\n address payable[] memory recipients,\n uint256[] memory amounts,\n int16 spec,\n address royaltyAddress,\n bool addToCache\n )\n {\n require(msg.sender == address(this), \"Only Engine\");\n\n royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n spec = _specCache[royaltyAddress];\n\n if (spec <= NOT_CONFIGURED && spec > NONE) {\n // No spec configured yet, so we need to detect the spec\n addToCache = true;\n\n // SuperRare handling\n if (tokenAddress == SuperRareContracts.SUPERRARE_V1 || tokenAddress == SuperRareContracts.SUPERRARE_V2) {\n try ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).tokenCreator(tokenAddress, tokenId)\n returns (address payable creator) {\n try ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).calculateRoyaltyFee(\n tokenAddress, tokenId, value\n ) returns (uint256 amount) {\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = creator;\n amounts[0] = amount;\n return (recipients, amounts, SUPERRARE, royaltyAddress, addToCache);\n } catch { }\n } catch { }\n }\n try IEIP2981(royaltyAddress).royaltyInfo(tokenId, value) returns (address recipient, uint256 amount) {\n require(amount < value, \"Invalid royalty amount\");\n uint32 recipientSize;\n assembly {\n recipientSize := extcodesize(recipient)\n }\n if (recipientSize > 0) {\n try IRoyaltySplitter(recipient).getRecipients() returns (Recipient[] memory splitRecipients) {\n recipients = new address payable[](splitRecipients.length);\n amounts = new uint256[](splitRecipients.length);\n uint256 sum = 0;\n uint256 splitRecipientsLength = splitRecipients.length;\n for (uint256 i = 0; i < splitRecipientsLength;) {\n Recipient memory splitRecipient = splitRecipients[i];\n recipients[i] = payable(splitRecipient.recipient);\n uint256 splitAmount = splitRecipient.bps * amount / 10000;\n amounts[i] = splitAmount;\n sum += splitAmount;\n unchecked {\n ++i;\n }\n }\n // sum can be less than amount, otherwise small-value listings can break\n require(sum <= amount, \"Invalid split\");\n\n return (recipients, amounts, ROYALTY_SPLITTER, royaltyAddress, addToCache);\n } catch { }\n }\n // Supports EIP2981. Return amounts\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = payable(recipient);\n amounts[0] = amount;\n return (recipients, amounts, EIP2981, royaltyAddress, addToCache);\n } catch { }\n try IManifold(royaltyAddress).getRoyalties(tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Supports manifold interface. Compute amounts\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), MANIFOLD, royaltyAddress, addToCache);\n } catch { }\n try IRaribleV2(royaltyAddress).getRaribleV2Royalties(tokenId) returns (IRaribleV2.Part[] memory royalties) {\n // Supports rarible v2 interface. Compute amounts\n recipients = new address payable[](royalties.length);\n amounts = new uint256[](royalties.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < royalties.length; i++) {\n recipients[i] = royalties[i].account;\n amounts[i] = value * royalties[i].value / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, RARIBLEV2, royaltyAddress, addToCache);\n } catch { }\n try IRaribleV1(royaltyAddress).getFeeRecipients(tokenId) returns (address payable[] memory recipients_) {\n // Supports rarible v1 interface. Compute amounts\n recipients_ = IRaribleV1(royaltyAddress).getFeeRecipients(tokenId);\n try IRaribleV1(royaltyAddress).getFeeBps(tokenId) returns (uint256[] memory bps) {\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), RARIBLEV1, royaltyAddress, addToCache);\n } catch { }\n } catch { }\n try IFoundation(royaltyAddress).getFees(tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Supports foundation interface. Compute amounts\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), FOUNDATION, royaltyAddress, addToCache);\n } catch { }\n try IZoraOverride(royaltyAddress).convertBidShares(tokenAddress, tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Support Zora override\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), ZORA, royaltyAddress, addToCache);\n } catch { }\n try IArtBlocksOverride(royaltyAddress).getRoyalties(tokenAddress, tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Support Art Blocks override\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), ARTBLOCKS, royaltyAddress, addToCache);\n } catch { }\n try IKODAV2Override(royaltyAddress).getKODAV2RoyaltyInfo(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients, uint256[] memory _amounts\n ) {\n // Support KODA V2 override\n require(_recipients.length == _amounts.length);\n return (_recipients, _amounts, KNOWNORIGINV2, royaltyAddress, addToCache);\n } catch { }\n\n try FALLBACK_REGISTRY.getRecipients(tokenAddress) returns (Recipient[] memory _recipients) {\n uint256 recipientsLength = _recipients.length;\n if (recipientsLength > 0) {\n return _calculateFallback(_recipients, recipientsLength, value, royaltyAddress, addToCache);\n }\n } catch { }\n\n // No supported royalties configured\n return (recipients, amounts, NONE, royaltyAddress, addToCache);\n } else {\n // Spec exists, just execute the appropriate one\n addToCache = false;\n if (spec == NONE) {\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == FALLBACK) {\n Recipient[] memory _recipients = FALLBACK_REGISTRY.getRecipients(tokenAddress);\n return _calculateFallback(_recipients, _recipients.length, value, royaltyAddress, addToCache);\n } else if (spec == MANIFOLD) {\n // Manifold spec\n uint256[] memory bps;\n (recipients, bps) = IManifold(royaltyAddress).getRoyalties(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == RARIBLEV2) {\n // Rarible v2 spec\n IRaribleV2.Part[] memory royalties;\n royalties = IRaribleV2(royaltyAddress).getRaribleV2Royalties(tokenId);\n recipients = new address payable[](royalties.length);\n amounts = new uint256[](royalties.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < royalties.length; i++) {\n recipients[i] = royalties[i].account;\n amounts[i] = value * royalties[i].value / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == RARIBLEV1) {\n // Rarible v1 spec\n uint256[] memory bps;\n recipients = IRaribleV1(royaltyAddress).getFeeRecipients(tokenId);\n bps = IRaribleV1(royaltyAddress).getFeeBps(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == FOUNDATION) {\n // Foundation spec\n uint256[] memory bps;\n (recipients, bps) = IFoundation(royaltyAddress).getFees(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == EIP2981 || spec == ROYALTY_SPLITTER) {\n // EIP2981 spec\n (address recipient, uint256 amount) = IEIP2981(royaltyAddress).royaltyInfo(tokenId, value);\n require(amount < value, \"Invalid royalty amount\");\n if (spec == ROYALTY_SPLITTER) {\n Recipient[] memory splitRecipients = IRoyaltySplitter(recipient).getRecipients();\n recipients = new address payable[](splitRecipients.length);\n amounts = new uint256[](splitRecipients.length);\n uint256 sum = 0;\n uint256 splitRecipientsLength = splitRecipients.length;\n for (uint256 i = 0; i < splitRecipientsLength;) {\n Recipient memory splitRecipient = splitRecipients[i];\n recipients[i] = payable(splitRecipient.recipient);\n uint256 splitAmount = splitRecipient.bps * amount / 10000;\n amounts[i] = splitAmount;\n sum += splitAmount;\n unchecked {\n ++i;\n }\n }\n // sum can be less than amount, otherwise small-value listings can break\n require(sum <= value, \"Invalid split\");\n\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n }\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = payable(recipient);\n amounts[0] = amount;\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == SUPERRARE) {\n // SUPERRARE spec\n address payable creator =\n ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).tokenCreator(tokenAddress, tokenId);\n uint256 amount = ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).calculateRoyaltyFee(\n tokenAddress, tokenId, value\n );\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = creator;\n amounts[0] = amount;\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == ZORA) {\n // Zora spec\n uint256[] memory bps;\n (recipients, bps) = IZoraOverride(royaltyAddress).convertBidShares(tokenAddress, tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == ARTBLOCKS) {\n // Art Blocks spec\n uint256[] memory bps;\n (recipients, bps) = IArtBlocksOverride(royaltyAddress).getRoyalties(tokenAddress, tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == KNOWNORIGINV2) {\n // KnownOrigin.io V2 spec (V3 falls under EIP2981)\n (recipients, amounts) =\n IKODAV2Override(royaltyAddress).getKODAV2RoyaltyInfo(tokenAddress, tokenId, value);\n require(recipients.length == amounts.length);\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n }\n }\n }\n\n function _calculateFallback(\n Recipient[] memory _recipients,\n uint256 recipientsLength,\n uint256 value,\n address royaltyAddress,\n bool addToCache\n )\n internal\n pure\n returns (\n address payable[] memory recipients,\n uint256[] memory amounts,\n int16 spec,\n address _royaltyAddress,\n bool _addToCache\n )\n {\n recipients = new address payable[](recipientsLength);\n amounts = new uint256[](recipientsLength);\n uint256 totalAmount;\n for (uint256 i = 0; i < recipientsLength;) {\n Recipient memory recipient = _recipients[i];\n recipients[i] = payable(recipient.recipient);\n uint256 amount = value * recipient.bps / 10_000;\n amounts[i] = amount;\n totalAmount += amount;\n unchecked {\n ++i;\n }\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, FALLBACK, royaltyAddress, addToCache);\n }\n\n /**\n * Compute royalty amounts\n */\n function _computeAmounts(uint256 value, uint256[] memory bps) private pure returns (uint256[] memory amounts) {\n amounts = new uint256[](bps.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < bps.length; i++) {\n amounts[i] = value * bps[i] / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return amounts;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\"; \nimport \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@manifoldxyz/libraries-solidity/contracts/access/IAdminControl.sol\";\n\nimport \"./IRoyaltyRegistry.sol\";\nimport \"./specs/INiftyGateway.sol\";\nimport \"./specs/IFoundation.sol\";\nimport \"./specs/IDigitalax.sol\";\nimport \"./specs/IArtBlocks.sol\";\n\n/**\n * @dev Registry to lookup royalty configurations\n */\ncontract RoyaltyRegistry is ERC165, OwnableUpgradeable, IRoyaltyRegistry {\n using AddressUpgradeable for address;\n\n address public immutable OVERRIDE_FACTORY;\n\n /**\n * @notice Constructor arg allows efficient lookup of override factory for single-tx overrides.\n * However, this means the RoyaltyRegistry will need to be upgraded if the override factory is changed.\n */\n constructor(address overrideFactory) {\n OVERRIDE_FACTORY = overrideFactory;\n }\n\n // Override addresses\n mapping(address => address) private _overrides;\n mapping(address => address) private _overrideLookupToTokenContract;\n\n function initialize(address _initialOwner) public initializer {\n _transferOwnership(_initialOwner);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override (ERC165, IERC165) returns (bool) {\n return interfaceId == type(IRoyaltyRegistry).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IRegistry-getRoyaltyLookupAddress}.\n */\n function getRoyaltyLookupAddress(address tokenAddress) external view override returns (address) {\n address override_ = _overrides[tokenAddress];\n if (override_ != address(0)) {\n return override_;\n }\n return tokenAddress;\n }\n\n /**\n * @dev See {IRegistry-getOverrideTokenAddress}.\n */\n function getOverrideLookupTokenAddress(address overrideAddress) external view override returns (address) {\n return _overrideLookupToTokenContract[overrideAddress];\n }\n\n /**\n * @dev See {IRegistry-setRoyaltyLookupAddress}.\n */\n function setRoyaltyLookupAddress(address tokenAddress, address royaltyLookupAddress)\n public\n override\n returns (bool)\n {\n require(\n tokenAddress.isContract() && (royaltyLookupAddress.isContract() || royaltyLookupAddress == address(0)),\n \"Invalid input\"\n );\n require(overrideAllowed(tokenAddress), \"Permission denied\");\n // look up existing override, if any\n address existingOverride = _overrides[tokenAddress];\n if (existingOverride != address(0)) {\n // delete existing override reverse-lookup\n _overrideLookupToTokenContract[existingOverride] = address(0);\n }\n _overrideLookupToTokenContract[royaltyLookupAddress] = tokenAddress;\n // set new override and reverse-lookup\n _overrides[tokenAddress] = royaltyLookupAddress;\n\n emit RoyaltyOverride(_msgSender(), tokenAddress, royaltyLookupAddress);\n return true;\n }\n\n /**\n * @dev See {IRegistry-overrideAllowed}.\n */\n function overrideAllowed(address tokenAddress) public view override returns (bool) {\n if (owner() == _msgSender()) return true;\n\n if (\n ERC165Checker.supportsInterface(tokenAddress, type(IAdminControl).interfaceId)\n && IAdminControl(tokenAddress).isAdmin(_msgSender())\n ) {\n return true;\n }\n\n try OwnableUpgradeable(tokenAddress).owner() returns (address owner) {\n if (owner == _msgSender()) return true;\n\n if (owner.isContract()) {\n try OwnableUpgradeable(owner).owner() returns (address passThroughOwner) {\n if (passThroughOwner == _msgSender()) return true;\n } catch { }\n }\n } catch { }\n\n try IAccessControlUpgradeable(tokenAddress).hasRole(0x00, _msgSender()) returns (bool hasRole) {\n if (hasRole) return true;\n } catch { }\n\n // Nifty Gateway overrides\n try INiftyBuilderInstance(tokenAddress).niftyRegistryContract() returns (address niftyRegistry) {\n try INiftyRegistry(niftyRegistry).isValidNiftySender(_msgSender()) returns (bool valid) {\n return valid;\n } catch { }\n } catch { }\n\n // OpenSea overrides\n // Tokens already support Ownable\n\n // Foundation overrides\n try IFoundationTreasuryNode(tokenAddress).getFoundationTreasury() returns (address payable foundationTreasury) {\n try IFoundationTreasury(foundationTreasury).isAdmin(_msgSender()) returns (bool isAdmin) {\n return isAdmin;\n } catch { }\n } catch { }\n\n // DIGITALAX overrides\n try IDigitalax(tokenAddress).accessControls() returns (address externalAccessControls) {\n try IDigitalaxAccessControls(externalAccessControls).hasAdminRole(_msgSender()) returns (bool hasRole) {\n if (hasRole) return true;\n } catch { }\n } catch { }\n\n // Art Blocks overrides\n try IArtBlocks(tokenAddress).admin() returns (address admin) {\n if (admin == _msgSender()) return true;\n } catch { }\n\n // Superrare overrides\n // Tokens and registry already support Ownable\n\n // Rarible overrides\n // Tokens already support Ownable\n\n return false;\n }\n\n function _msgSender() internal view virtual override (ContextUpgradeable) returns (address) {\n if (msg.sender == OVERRIDE_FACTORY) {\n address relayedSender;\n ///@solidity memory-safe-assembly\n assembly {\n // the factory appends the original msg.sender as last the word of calldata, which we can read using\n // calldataload\n relayedSender := calldataload(sub(calldatasize(), 0x20))\n }\n return relayedSender;\n }\n // otherwise return msg.sender as normal\n return msg.sender;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IArtBlocks.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Art Blocks nfts\n */\ninterface IArtBlocks {\n // document getter function of public variable\n function admin() external view returns (address);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IArtBlocksOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * Interface for an Art Blocks override\n */\ninterface IArtBlocksOverride {\n /**\n * @dev Get royalites of a token at a given tokenAddress.\n * Returns array of receivers and basisPoints.\n *\n * bytes4(keccak256('getRoyalties(address,uint256)')) == 0x9ca7dc7a\n *\n * => 0x9ca7dc7a = 0x9ca7dc7a\n */\n function getRoyalties(address tokenAddress, uint256 tokenId)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IDigitalax.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Digitalax nfts\n */\ninterface IDigitalax {\n function accessControls() external view returns (address);\n}\n\n/**\n * @dev Digitalax Access Controls Simple\n */\ninterface IDigitalaxAccessControls {\n function hasAdminRole(address _account) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IFoundation.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IFoundation {\n /*\n * bytes4(keccak256('getFees(uint256)')) == 0xd5a06d4c\n *\n * => 0xd5a06d4c = 0xd5a06d4c\n */\n function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);\n}\n\ninterface IFoundationTreasuryNode {\n function getFoundationTreasury() external view returns (address payable);\n}\n\ninterface IFoundationTreasury {\n function isAdmin(address account) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IKODAV2Override.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/// @author: knownorigin.io\n\npragma solidity ^0.8.0;\n\ninterface IKODAV2 {\n function editionOfTokenId(uint256 _tokenId) external view returns (uint256 _editionNumber);\n\n function artistCommission(uint256 _editionNumber)\n external\n view\n returns (address _artistAccount, uint256 _artistCommission);\n\n function editionOptionalCommission(uint256 _editionNumber)\n external\n view\n returns (uint256 _rate, address _recipient);\n}\n\ninterface IKODAV2Override {\n /// @notice Emitted when the royalties fee changes\n event CreatorRoyaltiesFeeUpdated(uint256 _oldCreatorRoyaltiesFee, uint256 _newCreatorRoyaltiesFee);\n\n /// @notice For the given KO NFT and token ID, return the addresses and the amounts to pay\n function getKODAV2RoyaltyInfo(address _tokenAddress, uint256 _id, uint256 _amount)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n\n /// @notice Allows the owner() to update the creator royalties\n function updateCreatorRoyalties(uint256 _creatorRoyaltiesFee) external;\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IManifold.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\n/**\n * @dev Royalty interface for creator core classes\n */\ninterface IManifold {\n /**\n * @dev Get royalites of a token. Returns list of receivers and basisPoints\n *\n * bytes4(keccak256('getRoyalties(uint256)')) == 0xbb3bafd6\n *\n * => 0xbb3bafd6 = 0xbb3bafd6\n */\n function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/INiftyGateway.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Nifty builder instance\n */\ninterface INiftyBuilderInstance {\n function niftyRegistryContract() external view returns (address);\n}\n\n/**\n * @dev Nifty registry\n */\ninterface INiftyRegistry {\n /**\n * @dev function to see if sending key is valid\n */\n function isValidNiftySender(address sending_key) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IRarible.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IRaribleV1 {\n /*\n * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f\n * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb\n *\n * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584\n */\n function getFeeBps(uint256 id) external view returns (uint256[] memory);\n function getFeeRecipients(uint256 id) external view returns (address payable[] memory);\n}\n\ninterface IRaribleV2 {\n /*\n * bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca\n */\n struct Part {\n address payable account;\n uint96 value;\n }\n\n function getRaribleV2Royalties(uint256 id) external view returns (Part[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/ISuperRare.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface ISuperRareRegistry {\n /**\n * @dev Get the royalty fee percentage for a specific ERC721 contract.\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n * @return uint8 wei royalty fee.\n */\n function getERC721TokenRoyaltyPercentage(address _contractAddress, uint256 _tokenId)\n external\n view\n returns (uint8);\n\n /**\n * @dev Utililty function to calculate the royalty fee for a token.\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n * @param _amount uint256 wei amount.\n * @return uint256 wei fee.\n */\n function calculateRoyaltyFee(address _contractAddress, uint256 _tokenId, uint256 _amount)\n external\n view\n returns (uint256);\n\n /**\n * @dev Get the token creator which will receive royalties of the given token\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n */\n function tokenCreator(address _contractAddress, uint256 _tokenId) external view returns (address payable);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IZoraOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * Paired down version of the Zora Market interface\n */\ninterface IZoraMarket {\n struct ZoraDecimal {\n uint256 value;\n }\n\n struct ZoraBidShares {\n // % of sale value that goes to the _previous_ owner of the nft\n ZoraDecimal prevOwner;\n // % of sale value that goes to the original creator of the nft\n ZoraDecimal creator;\n // % of sale value that goes to the seller (current owner) of the nft\n ZoraDecimal owner;\n }\n\n function bidSharesForToken(uint256 tokenId) external view returns (ZoraBidShares memory);\n}\n\n/**\n * Paired down version of the Zora Media interface\n */\ninterface IZoraMedia {\n /**\n * Auto-generated accessors of public variables\n */\n function marketContract() external view returns (address);\n function previousTokenOwners(uint256 tokenId) external view returns (address);\n function tokenCreators(uint256 tokenId) external view returns (address);\n\n /**\n * ERC721 function\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n}\n\n/**\n * Interface for a Zora media override\n */\ninterface IZoraOverride {\n /**\n * @dev Convert bid share configuration of a Zora Media token into an array of receivers and bps values\n * Does not support prevOwner and sell-on amounts as that is specific to Zora marketplace implementation\n * and requires updates on the Zora Media and Marketplace to update the sell-on amounts/previous owner values.\n * An off-Zora marketplace sale will break the sell-on functionality.\n */\n function convertBidShares(address media, uint256 tokenId)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC1155/IERC1155Upgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@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/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC1155/IERC1155.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981 is IERC165 {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/IERC721.sol\";\n" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\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/ERC1155/utils/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\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/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/ERC721/utils/ERC721Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Receiver.sol\";\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\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/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/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/ERC165Checker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface.\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&\n !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(\n address account,\n bytes4[] memory interfaceIds\n ) internal view returns (bool[] memory) {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n *\n * Some precompiled contracts will falsely indicate support for a given interface, so caution\n * should be exercised when using this function.\n *\n * Interface identification is specified in ERC-165.\n */\n function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\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" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable,\n IAccessControlUpgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable,\n IERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable,\n IERC1155MetadataURIUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ITokenUtils, IRoyaltyUGC} from \"./interfaces/ITokenUtils.sol\";\n\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771HandlerUpgradeable,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor,\n ITokenUtils\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_init(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(_manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: ids and metadataHash length mismatch\");\n require(ids.length == amounts.length, \"Asset: ids and amounts length mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {\n return hashUsed[metadataHash];\n }\n\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: not allowed to reuse metadata hash\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool)\n {\n return id == type(IRoyaltyUGC).interfaceId || super.supportsInterface(id);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\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 /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, recipient, creator);\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n /// @notice This function is used to register Asset contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Asset: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Asset: registry can't be zero address\");\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is\n IAssetCreate,\n Initializable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable,\n AccessControlUpgradeable\n{\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param metadataHashes The metadata hashes of the assets to mint\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint,\n /// @param creator The address of the creator\n function createSpecialAsset(\n bytes memory signature,\n uint256 amount,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, 0, amount, metadataHash, true);\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return The catalyst contract address\n function getCatalystContract() external view returns (address) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetCreate: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {IAssetReveal} from \"./interfaces/IAssetReveal.sol\";\n\n/// @title AssetReveal\n/// @author The Sandbox\n/// @notice Contract for burning and revealing assets\ncontract AssetReveal is\n IAssetReveal,\n Initializable,\n AccessControlUpgradeable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable\n{\n using TokenIdUtils for uint256;\n IAsset private assetContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator to asset id to asset's reveal nonce\n mapping(address => mapping(uint256 => uint16)) internal revealIds;\n\n // mapping for showing whether a revealHash has been used\n // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting\n mapping(bytes32 => bool) internal revealHashesUsed;\n\n bytes32 public constant REVEAL_TYPEHASH =\n keccak256(\n \"Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n bytes32 public constant BATCH_REVEAL_TYPEHASH =\n keccak256(\n \"BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)\"\n );\n bytes32 public constant INSTANT_REVEAL_TYPEHASH =\n keccak256(\n \"InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Reveal an asset to view its abilities and enhancements\n /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId\n /// @param tokenId the tokenId of id idasset to reveal\n /// @param amount the amount of tokens to reveal\n function revealBurn(uint256 tokenId, uint256 amount) external {\n _burnAsset(tokenId, amount);\n emit AssetRevealBurn(_msgSender(), tokenId, amount);\n }\n\n /// @notice Burn multiple assets to be able to reveal them later\n /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately\n /// @param tokenIds the tokenIds of the assets to burn\n /// @param amounts the amounts of the assets to burn\n function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external {\n _burnAssetBatch(tokenIds, amounts);\n emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for revealed asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function revealMint(\n bytes memory signature,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealMint signature\"\n );\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Mint multiple assets with revealed abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenIds The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\n function revealBatchMint(\n bytes calldata signature,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) external {\n require(prevTokenIds.length == amounts.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid metadataHashes length\");\n require(prevTokenIds.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealBatchMint signature\"\n );\n uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length);\n for (uint256 i = 0; i < prevTokenIds.length; i++) {\n newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]);\n }\n emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction\n /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\n /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param burnAmount The amount of assets to burn\n /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function burnAndReveal(\n bytes memory signature,\n uint256 prevTokenId,\n uint256 burnAmount,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid burnAndReveal signature\"\n );\n _burnAsset(prevTokenId, burnAmount);\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Generate new tokenIds for revealed assets and mint them\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param amounts The array of amounts to mint\n function _revealAsset(\n uint256 prevTokenId,\n string[] calldata metadataHashes,\n uint256[] calldata amounts,\n bytes32[] calldata revealHashes\n ) internal returns (uint256[] memory) {\n uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n require(revealHashesUsed[revealHashes[i]] == false, \"AssetReveal: RevealHash already used\");\n revealHashesUsed[revealHashes[i]] = true;\n }\n if (newTokenIds.length == 1) {\n assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]);\n } else {\n assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes);\n }\n return newTokenIds;\n }\n\n /// @notice Burns an asset to be able to reveal it later\n /// @param tokenId the tokenId of the asset to burn\n /// @param amount the amount of the asset to burn\n function _burnAsset(uint256 tokenId, uint256 amount) internal {\n _verifyBurnData(tokenId, amount);\n assetContract.burnFrom(_msgSender(), tokenId, amount);\n }\n\n function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal {\n require(tokenIds.length == amounts.length, \"AssetReveal: Invalid input\");\n for (uint256 i = 0; i < tokenIds.length; i++) {\n _verifyBurnData(tokenIds[i], amounts[i]);\n }\n assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts);\n }\n\n function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure {\n IAsset.AssetData memory data = tokenId.getData();\n require(!data.revealed, \"AssetReveal: Asset is already revealed\");\n require(amount > 0, \"AssetReveal: Burn amount should be greater than 0\");\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The address of the recipient\n /// @param prevTokenId The unrevealed token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashInstantReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n INSTANT_REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed token\n /// @param prevTokenId The previous token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed tokens\n /// @param prevTokenIds The previous token id\n /// @param amounts The amounts of tokens to mint\n /// @param metadataHashes The arrays of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashBatchReveal(\n address recipient,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n BATCH_REVEAL_TYPEHASH,\n recipient,\n keccak256(abi.encodePacked(prevTokenIds)),\n _encodeBatchAmounts(amounts),\n _encodeBatchHashes(metadataHashes),\n _encodeBatchRevealHashes(revealHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = _encodeHashes(metadataHashes[i]);\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param revealHashes The revealHashes\n /// @return encodedRevealHashes The encoded hashes of the metadata\n function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](revealHashes.length);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i]));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the amounts of the tokens for signature verification\n /// @param amounts The amounts of the tokens\n /// @return encodedAmounts The encoded amounts of the tokens\n function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) {\n bytes32[] memory encodedAmounts = new bytes32[](amounts.length);\n for (uint256 i = 0; i < amounts.length; i++) {\n encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i]));\n }\n return keccak256(abi.encodePacked(encodedAmounts));\n }\n\n /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't\n /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed\n /// @param metadataHashes The hashes of the metadata\n /// @param prevTokenId The previous token id from which the assets are revealed\n /// @return tokenIdArray The array of tokenIds to mint\n function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId)\n internal\n returns (uint256[] memory)\n {\n IAsset.AssetData memory data = prevTokenId.getData();\n require(!data.revealed, \"AssetReveal: already revealed\");\n uint256[] memory tokenIdArray = new uint256[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]);\n if (tokenId == 0) {\n uint16 revealNonce = ++revealIds[data.creator][prevTokenId];\n tokenId = TokenIdUtils.generateTokenId(\n data.creator,\n data.tier,\n data.creatorNonce,\n revealNonce,\n data.bridged\n );\n }\n tokenIdArray[i] = tokenId;\n }\n return tokenIdArray;\n }\n\n /// @notice Get the status of a revealHash\n /// @return Whether it has been used\n function revealHashUsed(bytes32 revealHash) external view returns (bool) {\n return revealHashesUsed[revealHash];\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: signer not set\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771HandlerUpgradeable,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_init(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771HandlerAbstract) returns (address) {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `interfaceId`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Catalyst: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Catalyst: registry can't be zero address\");\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetReveal {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetRevealBurn(address revealer, uint256 unrevealedTokenId, uint256 amount);\n event AssetRevealBatchBurn(address revealer, uint256[] unrevealedTokenIds, uint256[] amounts);\n event AssetRevealMint(\n address recipient,\n uint256 unrevealedTokenId,\n uint256[] amounts,\n uint256[] newTokenIds,\n bytes32[] revealHashes\n );\n event AssetRevealBatchMint(\n address recipient,\n uint256[] unrevealedTokenIds,\n uint256[][] amounts,\n uint256[][] newTokenIds,\n bytes32[][] revealHashes\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IRoyaltyUGC} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\";\n\ninterface ITokenUtils is IRoyaltyUGC {\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\n\n function isRevealed(uint256 tokenId) external pure returns (bool);\n\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16);\n\n function getRevealNonce(uint256 tokenId) external pure returns (uint16);\n\n function isBridged(uint256 tokenId) external pure returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/FallBackRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n FallbackRegistry\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/FallbackRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetReveal} from \"../AssetReveal.sol\";\n\ncontract MockAssetReveal is AssetReveal {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketplace.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockMarketplace\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/MockMarketplace.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace1\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace2.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace2\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace3.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace3\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace4.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace4\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMinter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\nimport {TokenIdUtils} from \"../libraries/TokenIdUtils.sol\";\n\ncontract MockMinter {\n using TokenIdUtils for uint256;\n\n IAsset public assetContract;\n\n mapping(address => uint16) public creatorNonces;\n\n event Minted(uint256 tokenId, uint256 amount);\n\n constructor(address _assetContract) {\n assetContract = IAsset(_assetContract);\n }\n\n /// @dev Mints a specified number of unrevealed copies of specific tier\n function mintAsset(\n address recipient,\n uint256 amount,\n uint8 tier,\n bool revealed,\n string calldata metadataHash\n ) public {\n // increment nonce\n unchecked {creatorNonces[msg.sender]++;}\n // get current creator nonce\n uint16 creatorNonce = creatorNonces[msg.sender];\n uint256 tokenId = TokenIdUtils.generateTokenId(msg.sender, tier, creatorNonce, revealed ? 1 : 0, false);\n\n assetContract.mint(recipient, tokenId, amount, metadataHash);\n emit Minted(tokenId, amount);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockOperatorFilterRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockOperatorFilterSubscription.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockOperatorFilterSubscription\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockTrustedForwarder.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {MockTrustedForwarder} from \"@sandbox-smart-contracts/dependency-metatx/contracts/test/MockTrustedForwarder.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyEngineV1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n RoyaltyEngineV1\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyManager} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n RoyaltyRegistry\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltySplitter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltySplitter} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\";\n\n/* solhint-disable-next-line no-empty-blocks*/\ncontract MockSplitter is RoyaltySplitter {\n\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/TestERC20.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {TestERC20} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC20.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/TokenIdUtilsWrapped.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {TokenIdUtils} from \"../libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\ncontract TokenIdUtilsWrapped {\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) public pure returns (uint256 tokenId) {\n return TokenIdUtils.generateTokenId(creator, tier, creatorNonce, revealNonce, bridged);\n }\n\n function getCreatorAddress(uint256 tokenId) public pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n function getTier(uint256 tokenId) public pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n function getCreatorNonce(uint256 tokenId) public pure returns (uint16 creatorNonce) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n function isRevealed(uint256 tokenId) public pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n function getRevealNonce(uint256 tokenId) public pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n function isBridged(uint256 tokenId) public pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n function getData(uint256 tokenId) public pure returns (IAsset.AssetData memory data) {\n return TokenIdUtils.getData(tokenId);\n }\n\n function TIER_MASK() public pure returns (uint256) {\n return TokenIdUtils.TIER_MASK;\n }\n\n function NONCE_MASK() public pure returns (uint256) {\n return TokenIdUtils.NONCE_MASK;\n }\n\n function REVEAL_NONCE_MASK() public pure returns (uint256) {\n return TokenIdUtils.REVEAL_NONCE_MASK;\n }\n\n function BRIDGED_MASK() public pure returns (uint256) {\n return TokenIdUtils.BRIDGED_MASK;\n }\n\n function TIER_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.TIER_SHIFT;\n }\n\n function NONCE_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.NONCE_SHIFT;\n }\n\n function REVEAL_NONCE_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.REVEAL_NONCE_SHIFT;\n }\n\n function BRIDGED_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.BRIDGED_SHIFT;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\nabstract contract ERC2771HandlerAbstract {\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function isTrustedForwarder(address forwarder) external view returns (bool) {\n return _isTrustedForwarder(forwarder);\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual returns (address sender) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n sender = msg.sender;\n }\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual returns (bytes calldata) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n /// @dev this function must be IMPLEMENTED\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC2771HandlerAbstract} from \"./ERC2771HandlerAbstract.sol\";\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\n address private _trustedForwarder;\n\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\n /// @param oldTrustedForwarder old trusted forwarder\n /// @param newTrustedForwarder new trusted forwarder\n /// @param operator the sender of the transaction\n event TrustedForwarderSet(\n address indexed oldTrustedForwarder,\n address indexed newTrustedForwarder,\n address indexed operator\n );\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\n __ERC2771Handler_init_unchained(forwarder);\n }\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\n _setTrustedForwarder(forwarder);\n }\n\n /// @notice return the address of the trusted forwarder\n /// @return return the address of the trusted forwarder\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n /// @notice set the address of the trusted forwarder\n /// @param newForwarder the address of the new forwarder.\n function _setTrustedForwarder(address newForwarder) internal virtual {\n require(newForwarder != _trustedForwarder, \"ERC2771HandlerUpgradeable: forwarder already set\");\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\n _trustedForwarder = newForwarder;\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/test/MockTrustedForwarder.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.2;\n\ncontract MockTrustedForwarder {\n struct ForwardRequest {\n address from;\n address to;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n\n function execute(ForwardRequest calldata req) public payable returns (bool, bytes memory) {\n (bool success, bytes memory returndata) = req.to.call{gas: req.gasLimit, value: req.value}(\n abi.encodePacked(req.data, req.from)\n );\n assert(gasleft() > req.gasLimit / 63);\n return (success, returndata);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace1 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace2 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace3 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace4 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"operator-filter-registry/src/IOperatorFilterRegistry.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n OperatorFilterRegistryErrorsAndEvents\n} from \"operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol\";\n\n/**\n * @title MockOperatorFilterRegistry\n * @notice Made based on the OperatorFilterRegistry of openSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol\n * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be\n * * restricted according to the isOperatorAllowed function.\n */\ncontract MockOperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)\n /// Note that this will also be a smart contract's codehash when making calls from its constructor.\n bytes32 internal constant EOA_CODEHASH = keccak256(\"\");\n\n mapping(address => EnumerableSet.AddressSet) private _filteredOperators;\n mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;\n mapping(address => address) private _registrations;\n mapping(address => EnumerableSet.AddressSet) private _subscribers;\n\n constructor(address _defaultSubscription, address[] memory _blacklistedAddresses) {\n _registrations[_defaultSubscription] = _defaultSubscription;\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[_defaultSubscription];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[_defaultSubscription];\n for (uint256 i; i < _blacklistedAddresses.length; i++) {\n filteredOperatorsRef.add(_blacklistedAddresses[i]);\n bytes32 codeHash = _blacklistedAddresses[i].codehash;\n filteredCodeHashesRef.add(codeHash);\n }\n }\n\n /**\n * @notice Restricts method caller to the address or EIP-173 \"owner()\"\n */\n modifier onlyAddressOrOwner(address addr) {\n if (msg.sender != addr) {\n try Ownable(addr).owner() returns (address owner) {\n if (msg.sender != owner) {\n revert OnlyAddressOrOwner();\n }\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NotOwnable();\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n }\n _;\n }\n\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n * Note that this method will *revert* if an operator or its codehash is filtered with an error that is\n * more informational than a false boolean, so smart contracts that query this method for informational\n * purposes will need to wrap in a try/catch or perform a low-level staticcall in order to handle the case\n * that an operator is filtered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n EnumerableSet.AddressSet storage filteredOperatorsRef;\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef;\n\n filteredOperatorsRef = _filteredOperators[registration];\n filteredCodeHashesRef = _filteredCodeHashes[registration];\n\n if (filteredOperatorsRef.contains(operator)) {\n revert AddressFiltered(operator);\n }\n if (operator.code.length > 0) {\n bytes32 codeHash = operator.codehash;\n if (filteredCodeHashesRef.contains(codeHash)) {\n revert CodeHashFiltered(operator, codeHash);\n }\n }\n }\n return true;\n }\n\n //////////////////\n // AUTH METHODS //\n //////////////////\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external onlyAddressOrOwner(registrant) {\n if (_registrations[registrant] != address(0)) {\n revert AlreadyRegistered();\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n }\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address registrant) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = address(0);\n emit RegistrationUpdated(registrant, false);\n }\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n if (registrant == subscription) {\n revert CannotSubscribeToSelf();\n }\n address subscriptionRegistration = _registrations[subscription];\n if (subscriptionRegistration == address(0)) {\n revert NotRegistered(subscription);\n }\n if (subscriptionRegistration != subscription) {\n revert CannotSubscribeToRegistrantWithSubscription(subscription);\n }\n\n _registrations[registrant] = subscription;\n _subscribers[subscription].add(registrant);\n emit RegistrationUpdated(registrant, true);\n emit SubscriptionUpdated(registrant, subscription, true);\n }\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy)\n external\n onlyAddressOrOwner(registrant)\n {\n if (registrantToCopy == registrant) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n _copyEntries(registrant, registrantToCopy);\n }\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n\n if (!filtered) {\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n } else {\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n }\n emit OperatorUpdated(registrant, operator, filtered);\n }\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codeHash,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n\n if (!filtered) {\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n } else {\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n }\n emit CodeHashUpdated(registrant, codeHash, filtered);\n }\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n uint256 operatorsLength = operators.length;\n if (!filtered) {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n unchecked {++i;}\n }\n }\n emit OperatorsUpdated(registrant, operators, filtered);\n }\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n uint256 codeHashesLength = codeHashes.length;\n if (!filtered) {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n unchecked {++i;}\n }\n }\n emit CodeHashesUpdated(registrant, codeHashes, filtered);\n }\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {\n if (registrant == newSubscription) {\n revert CannotSubscribeToSelf();\n }\n if (newSubscription == address(0)) {\n revert CannotSubscribeToZeroAddress();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == newSubscription) {\n revert AlreadySubscribed(newSubscription);\n }\n address newSubscriptionRegistration = _registrations[newSubscription];\n if (newSubscriptionRegistration == address(0)) {\n revert NotRegistered(newSubscription);\n }\n if (newSubscriptionRegistration != newSubscription) {\n revert CannotSubscribeToRegistrantWithSubscription(newSubscription);\n }\n\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = newSubscription;\n _subscribers[newSubscription].add(registrant);\n emit SubscriptionUpdated(registrant, newSubscription, true);\n }\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == registrant) {\n revert NotSubscribed();\n }\n _subscribers[registration].remove(registrant);\n _registrations[registrant] = registrant;\n emit SubscriptionUpdated(registrant, registration, false);\n if (copyExistingEntries) {\n _copyEntries(registrant, registration);\n }\n }\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {\n if (registrant == registrantToCopy) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _copyEntries(registrant, registrantToCopy);\n }\n\n /// @dev helper to copy entries from registrantToCopy to registrant and emit events\n function _copyEntries(address registrant, address registrantToCopy) private {\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];\n uint256 filteredOperatorsLength = filteredOperatorsRef.length();\n uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();\n for (uint256 i = 0; i < filteredOperatorsLength; ) {\n address operator = filteredOperatorsRef.at(i);\n bool added = _filteredOperators[registrant].add(operator);\n if (added) {\n emit OperatorUpdated(registrant, operator, true);\n }\n unchecked {++i;}\n }\n for (uint256 i = 0; i < filteredCodeHashesLength; ) {\n bytes32 codehash = filteredCodeHashesRef.at(i);\n bool added = _filteredCodeHashes[registrant].add(codehash);\n if (added) {\n emit CodeHashUpdated(registrant, codehash, true);\n }\n unchecked {++i;}\n }\n }\n\n //////////////////\n // VIEW METHODS //\n //////////////////\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address registrant) external view returns (address subscription) {\n subscription = _registrations[registrant];\n if (subscription == address(0)) {\n revert NotRegistered(registrant);\n } else if (subscription == registrant) {\n subscription = address(0);\n }\n }\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external view returns (address[] memory) {\n return _subscribers[registrant].values();\n }\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external view returns (address) {\n return _subscribers[registrant].at(index);\n }\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].contains(operator);\n }\n return _filteredOperators[registrant].contains(operator);\n }\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {\n bytes32 codeHash = operatorWithCode.codehash;\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address registrant) external view returns (bool) {\n return _registrations[registrant] != address(0);\n }\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address registrant) external view returns (address[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].values();\n }\n return _filteredOperators[registrant].values();\n }\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].values();\n }\n return _filteredCodeHashes[registrant].values();\n }\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].at(index);\n }\n return _filteredOperators[registrant].at(index);\n }\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].at(index);\n }\n return _filteredCodeHashes[registrant].at(index);\n }\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address a) external view returns (bytes32) {\n return a.codehash;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"operator-filter-registry/src/IOperatorFilterRegistry.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\n/**\n * @title OwnedRegistrant\n * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,\n * to facilitate a subscription whose ownership can be transferred.\n */\n\ncontract MockOperatorFilterSubscription is Ownable2Step {\n address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);\n\n /// @dev The constructor that is called when the contract is being deployed.\n /// @dev This contract is based on OpenSea's OwnedRegistrant.\n /// @dev The param _localRegistry has been added to the constructor to enable local testing.\n constructor(address _owner, address _localRegistry) {\n IOperatorFilterRegistry(_localRegistry).registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);\n transferOwnership(_owner);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IERC20Approve {\n function approve(address spender, uint256 amount) external returns (bool);\n\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IMultiRoyaltyRecipients} from \"./IMultiRoyaltyRecipients.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyDistributor is IERC165, IMultiRoyaltyRecipients {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, address recipient);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address recipient);\n\n event RoyaltyRecipientSet(address splitter, address recipient);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyRecipients is IERC165 {\n /**\n * @dev Helper function to get all recipients\n */\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address payable, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\n\n function setTrustedForwarder(address _newForwarder) external;\n\n function getTrustedForwarder() external view returns (address);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IRoyaltyUGC {\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/FallbackRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {FallbackRegistry} from \"@manifoldxyz/royalty-registry-solidity/contracts/FallbackRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/MockMarketplace.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981} from \"@openzeppelin/contracts/interfaces/IERC2981.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/interfaces/IERC1155.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/interfaces/IERC721.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport {IRoyaltyEngineV1} from \"@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyEngineV1.sol\";\n\ncontract MockMarketplace {\n IRoyaltyEngineV1 public royaltyEngine;\n\n constructor(address _royaltyEngine) {\n royaltyEngine = IRoyaltyEngineV1(_royaltyEngine);\n }\n\n function distributeRoyaltyEIP2981(\n uint256 erc20TokenAmount,\n IERC20 erc20Contract,\n address nftContract,\n uint256 nftId,\n address nftBuyer,\n address nftSeller,\n bool is1155\n ) external payable {\n if (msg.value == 0) {\n require(erc20TokenAmount > 0, \"erc20 token ammount can't be zero\");\n (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, erc20TokenAmount);\n erc20Contract.transferFrom(nftBuyer, royaltyReceiver, value);\n erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - value));\n } else {\n (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, msg.value);\n (bool sent, ) = royaltyReceiver.call{value: value}(\"\");\n require(sent, \"Failed to send distributeRoyaltyEIP2981Ether\");\n (bool sentToSeller, ) = nftSeller.call{value: msg.value - value}(\"\");\n require(sentToSeller, \"Failed to send to seller\");\n }\n if (is1155) {\n IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, \"0x\");\n } else {\n IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, \"0x\");\n }\n }\n\n function distributeRoyaltyRoyaltyEngine(\n uint256 erc20TokenAmount,\n IERC20 erc20Contract,\n address nftContract,\n uint256 nftId,\n address nftBuyer,\n address nftSeller,\n bool is1155\n ) external payable {\n if (msg.value == 0) {\n require(erc20TokenAmount > 0, \"erc20 token ammount can't be zero\");\n uint256 TotalRoyalty;\n (address payable[] memory recipients, uint256[] memory amounts) =\n royaltyEngine.getRoyalty(address(nftContract), nftId, erc20TokenAmount);\n for (uint256 i; i < recipients.length; i++) {\n erc20Contract.transferFrom(nftBuyer, recipients[i], amounts[i]);\n TotalRoyalty += amounts[i];\n }\n erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - TotalRoyalty));\n } else {\n (address payable[] memory recipients, uint256[] memory amounts) =\n royaltyEngine.getRoyalty(address(nftContract), nftId, msg.value);\n uint256 TotalRoyalty;\n for (uint256 i; i < recipients.length; i++) {\n (bool sent, ) = recipients[i].call{value: amounts[i]}(\"\");\n require(sent, \"Failed to send Ether\");\n TotalRoyalty += amounts[i];\n }\n (bool sentToSeller, ) = nftSeller.call{value: msg.value - TotalRoyalty}(\"\");\n require(sentToSeller, \"Failed to send to seller\");\n }\n if (is1155) {\n IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, \"0x\");\n } else {\n IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, \"0x\");\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyEngineV1} from \"@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyEngineV1.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyRegistry} from \"@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC20.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n/* solhint-disable-next-line no-empty-blocks*/\n\npragma solidity ^0.8.0;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n /* solhint-disable-next-line no-empty-blocks*/\n constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\nimport {IMultiRoyaltyDistributor, IMultiRoyaltyRecipients} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributer\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributer contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to slip its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n address public royaltyManager;\n\n mapping(uint256 => address payable) public _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n function __MultiRoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = _royaltyManager;\n }\n\n /// @notice EIP 165 interface function\n /// @dev used to check the interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n interfaceId == type(IMultiRoyaltyRecipients).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) internal {\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n _tokenRoyaltiesSplitter[tokenId] = creatorSplitterAddress;\n _tokensWithRoyalties.push(tokenId);\n emit TokenRoyaltySet(tokenId, recipient);\n }\n\n /// @notice Returns royalty receivers and their split of royalty for each token\n /// @return royaltyConfigs receivers and their split array as long as the number of tokens.\n function getTokenRoyalties() external view override returns (TokenRoyaltyConfig[] memory royaltyConfigs) {\n royaltyConfigs = new TokenRoyaltyConfig[](_tokensWithRoyalties.length);\n for (uint256 i; i < _tokensWithRoyalties.length; ++i) {\n TokenRoyaltyConfig memory royaltyConfig;\n uint256 tokenId = _tokensWithRoyalties[i];\n address splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n royaltyConfig.recipients = IRoyaltySplitter(splitterAddress).getRecipients();\n }\n royaltyConfig.tokenId = tokenId;\n royaltyConfigs[i] = royaltyConfig;\n }\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return address the royalty receiver\n /// @return value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value) public view override returns (address, uint256) {\n (address payable _defaultRoyaltyReceiver, uint16 _defaultRoyaltyBPS) =\n IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return addresses of royalty recipient of the token.\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n Recipient[] memory defaultRecipient = new Recipient[](1);\n defaultRecipient[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return defaultRecipient;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n ERC165Upgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public _creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n address internal _trustedForwarder;\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n /// @param trustedForwarder the trustedForwarder address for royalty splitters to use.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter,\n address trustedForwarder\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n _trustedForwarder = trustedForwarder;\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[msg.sender];\n require(creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(creatorSplitterAddress)._recipient();\n require(_recipient != recipient, \"Manager: Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the trustedForwarder address to be used by the splitters\n /// @dev can only be called by the admin\n /// @param _newForwarder is the new trusted forwarder address\n /// @dev new splitters will be deployed with this setting; existing splitters will have to apply it\n function setTrustedForwarder(address _newForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _trustedForwarder = _newForwarder;\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n /// @notice get the current trustedForwarder address\n function getTrustedForwarder() public view returns (address) {\n return _trustedForwarder;\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set split greater than the total basis point\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n recipient = Recipient({recipient: commonRecipient, bps: commonSplit});\n return recipient;\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress deployed for a creator\n function deploySplitter(address creator, address payable recipient) external returns (address payable) {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n _creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable) {\n return _creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @return commonRecipient\n /// @return royaltySplit\n function getRoyaltyInfo() external view returns (address payable, uint16) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @param _contractAddress the address of the contract for which the royalty is required.\n /// @return royaltyBps royalty bps of the contarct\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) {\n return contractRoyalty[_contractAddress];\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OwnableUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is\n Initializable,\n OwnableUpgradeable,\n IRoyaltySplitter,\n ERC165Upgradeable,\n ERC2771HandlerAbstract\n{\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n uint256 internal constant IERC20_APPROVE_SELECTOR =\n 0x095ea7b300000000000000000000000000000000000000000000000000000000;\n uint256 internal constant SELECTOR_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000;\n\n address payable public _recipient;\n IRoyaltyManager public _royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipient the wallet of the creator when the contract is deployed\n /// @param royaltyManager the address of the royalty manager contract\n function initialize(address payable recipient, address royaltyManager) public initializer {\n _royaltyManager = IRoyaltyManager(royaltyManager); // set manager before Ownable_init for _isTrustedForwarder\n _recipient = recipient;\n __Ownable_init();\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n _setRecipients(recipients);\n }\n\n function _setRecipients(Recipient[] calldata recipients) private {\n delete _recipient;\n require(recipients.length == 1, \"Invalid recipents length\");\n _recipient = recipients[0].recipient;\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients of royalty through this splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory recipients = new Recipient[](2);\n recipients[0].recipient = _recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() public payable {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n amountToSend = (value * recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) public {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == _msgSender() || _recipient == _msgSender(),\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n bool success;\n (success, amountToSend) = balance.tryMul(recipient.bps);\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n try erc20Contract.transfer(recipient.recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), recipient.recipient, amountToSend);\n } catch {\n return false;\n }\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n try erc20Contract.transfer(_recipients[0].recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n } catch {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice made for unexpected scenarios when assets are sent to this contact such that they could be recovered.\n /// @dev first attempts to split ERC20 tokens.\n /// @param target target of the call\n /// @param callData for the call.\n function proxyCall(address payable target, bytes calldata callData) external {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n require(\n commonRecipient.recipient == _msgSender() || _recipient == _msgSender(),\n \"Split: Can only be called by one of the recipients\"\n );\n require(\n !callData.startsWith(IERC20Approve.approve.selector) &&\n !callData.startsWith(IERC20Approve.increaseAllowance.selector),\n \"Split: ERC20 tokens must be split\"\n );\n /* solhint-disable-next-line no-empty-blocks*/\n try this.splitERC20Tokens(IERC20(target)) {} catch {}\n target.functionCall(callData);\n }\n\n /// @notice verify whether a forwarder address is the trustedForwarder address, using the manager setting\n /// @dev this function is used to avoid having a trustedForwarder variable inside the splitter\n /// @return bool whether the forwarder is the trusted address\n function _isTrustedForwarder(address forwarder) internal view override(ERC2771HandlerAbstract) returns (bool) {\n return forwarder == _royaltyManager.getTrustedForwarder();\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + }, + "operator-filter-registry/src/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(address registrant, address operator, bool filtered) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(address registrant, address[] calldata operators, bool filtered) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ncontract OperatorFilterRegistryErrorsAndEvents {\n /// @notice Emitted when trying to register an address that has no code.\n error CannotFilterEOAs();\n\n /// @notice Emitted when trying to add an address that is already filtered.\n error AddressAlreadyFiltered(address operator);\n\n /// @notice Emitted when trying to remove an address that is not filtered.\n error AddressNotFiltered(address operator);\n\n /// @notice Emitted when trying to add a codehash that is already filtered.\n error CodeHashAlreadyFiltered(bytes32 codeHash);\n\n /// @notice Emitted when trying to remove a codehash that is not filtered.\n error CodeHashNotFiltered(bytes32 codeHash);\n\n /// @notice Emitted when the caller is not the address or EIP-173 \"owner()\"\n error OnlyAddressOrOwner();\n\n /// @notice Emitted when the registrant is not registered.\n error NotRegistered(address registrant);\n\n /// @notice Emitted when the registrant is already registered.\n error AlreadyRegistered();\n\n /// @notice Emitted when the registrant is already subscribed.\n error AlreadySubscribed(address subscription);\n\n /// @notice Emitted when the registrant is not subscribed.\n error NotSubscribed();\n\n /// @notice Emitted when trying to update a registration where the registrant is already subscribed.\n error CannotUpdateWhileSubscribed(address subscription);\n\n /// @notice Emitted when trying to subscribe to itself.\n error CannotSubscribeToSelf();\n\n /// @notice Emitted when trying to subscribe to the zero address.\n error CannotSubscribeToZeroAddress();\n\n /// @notice Emitted when trying to register and the contract is not ownable (EIP-173 \"owner()\")\n error NotOwnable();\n\n /// @notice Emitted when an address is filtered.\n error AddressFiltered(address filtered);\n\n /// @notice Emitted when a codeHash is filtered.\n error CodeHashFiltered(address account, bytes32 codeHash);\n\n /// @notice Emited when trying to register to a registrant with a subscription.\n error CannotSubscribeToRegistrantWithSubscription(address registrant);\n\n /// @notice Emitted when trying to copy a registration from itself.\n error CannotCopyFromSelf();\n\n /// @notice Emitted when a registration is updated.\n event RegistrationUpdated(address indexed registrant, bool indexed registered);\n\n /// @notice Emitted when an operator is updated.\n event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);\n\n /// @notice Emitted when multiple operators are updated.\n event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);\n\n /// @notice Emitted when a codeHash is updated.\n event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);\n\n /// @notice Emitted when multiple codeHashes are updated.\n event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);\n\n /// @notice Emitted when a subscription is updated.\n event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/952d3f5cbc56ccf43c51c41fe7c707af.json b/packages/deploy/deployments/mumbai/solcInputs/952d3f5cbc56ccf43c51c41fe7c707af.json new file mode 100644 index 0000000000..f14f73550b --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/952d3f5cbc56ccf43c51c41fe7c707af.json @@ -0,0 +1,257 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/libraries-solidity/contracts/access/IAdminControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface for admin control\n */\ninterface IAdminControl is IERC165 {\n\n event AdminApproved(address indexed account, address indexed sender);\n event AdminRevoked(address indexed account, address indexed sender);\n\n /**\n * @dev gets address of all admins\n */\n function getAdmins() external view returns (address[] memory);\n\n /**\n * @dev add an admin. Can only be called by contract owner.\n */\n function approveAdmin(address admin) external;\n\n /**\n * @dev remove an admin. Can only be called by contract owner.\n */\n function revokeAdmin(address admin) external;\n\n /**\n * @dev checks whether or not given address is an admin\n * Returns True if they are\n */\n function isAdmin(address admin) external view returns (bool);\n\n}" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/FallbackRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport { Recipient } from \"./overrides/IRoyaltySplitter.sol\";\nimport { Ownable2Step } from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport { IFallbackRegistry } from \"./overrides/IFallbackRegistry.sol\";\n\ncontract FallbackRegistry is IFallbackRegistry, Ownable2Step {\n struct TokenFallback {\n address tokenAddress;\n Recipient[] recipients;\n }\n\n mapping(address => Recipient[]) fallbacks;\n\n constructor(address initialOwner) {\n _transferOwnership(initialOwner);\n }\n\n function setFallback(address tokenAddress, Recipient[] calldata _recipients) public onlyOwner {\n Recipient[] storage recipients = fallbacks[tokenAddress];\n uint256 recipientsLength = _recipients.length;\n ///@solidity memory-safe-assembly\n assembly {\n // overwrite length directly rather than deleting and then updating it each time we push new values\n // this means if the new array is shorter than the old ones, those slots will stay dirty, but they\n // should not be able to be accessed due to the new length\n sstore(recipients.slot, recipientsLength)\n }\n for (uint256 i; i < recipientsLength;) {\n recipients[i] = _recipients[i];\n unchecked {\n ++i;\n }\n }\n }\n\n function setFallbacks(TokenFallback[] calldata bundle) external onlyOwner {\n uint256 bundleLength = bundle.length;\n for (uint256 i = 0; i < bundleLength;) {\n TokenFallback calldata tokenFallback = bundle[i];\n setFallback(tokenFallback.tokenAddress, tokenFallback.recipients);\n unchecked {\n ++i;\n }\n }\n }\n\n function getRecipients(address tokenAddress) external view returns (Recipient[] memory) {\n return fallbacks[tokenAddress];\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyEngineV1.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Lookup engine interface\n */\ninterface IRoyaltyEngineV1 is IERC165 {\n /**\n * Get the royalty for a given token (address, id) and value amount. Does not cache the bps/amounts. Caches the spec for a given token address\n *\n * @param tokenAddress - The address of the token\n * @param tokenId - The id of the token\n * @param value - The value you wish to get the royalty of\n *\n * returns Two arrays of equal length, royalty recipients and the corresponding amount each recipient should get\n */\n function getRoyalty(address tokenAddress, uint256 tokenId, uint256 value)\n external\n returns (address payable[] memory recipients, uint256[] memory amounts);\n\n /**\n * View only version of getRoyalty\n *\n * @param tokenAddress - The address of the token\n * @param tokenId - The id of the token\n * @param value - The value you wish to get the royalty of\n *\n * returns Two arrays of equal length, royalty recipients and the corresponding amount each recipient should get\n */\n function getRoyaltyView(address tokenAddress, uint256 tokenId, uint256 value)\n external\n view\n returns (address payable[] memory recipients, uint256[] memory amounts);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Royalty registry interface\n */\ninterface IRoyaltyRegistry is IERC165 {\n event RoyaltyOverride(address owner, address tokenAddress, address royaltyAddress);\n\n /**\n * Override the location of where to look up royalty information for a given token contract.\n * Allows for backwards compatibility and implementation of royalty logic for contracts that did not previously support them.\n *\n * @param tokenAddress - The token address you wish to override\n * @param royaltyAddress - The royalty override address\n */\n function setRoyaltyLookupAddress(address tokenAddress, address royaltyAddress) external returns (bool);\n\n /**\n * Returns royalty address location. Returns the tokenAddress by default, or the override if it exists\n *\n * @param tokenAddress - The token address you are looking up the royalty for\n */\n function getRoyaltyLookupAddress(address tokenAddress) external view returns (address);\n\n /**\n * Returns the token address that an overrideAddress is set for.\n * Note: will not be accurate if the override was created before this function was added.\n *\n * @param overrideAddress - The override address you are looking up the token for\n */\n function getOverrideLookupTokenAddress(address overrideAddress) external view returns (address);\n\n /**\n * Whether or not the message sender can override the royalty address for the given token address\n *\n * @param tokenAddress - The token address you are looking up the royalty for\n */\n function overrideAllowed(address tokenAddress) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/SuperRareContracts.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary SuperRareContracts {\n address public constant SUPERRARE_REGISTRY = 0x17B0C8564E53f22364A6C8de6F7ca5CE9BEa4e5D;\n address public constant SUPERRARE_V1 = 0x41A322b28D0fF354040e2CbC676F0320d8c8850d;\n address public constant SUPERRARE_V2 = 0xb932a70A57673d89f4acfFBE830E8ed7f75Fb9e0;\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IFallbackRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport { Recipient } from \"./IRoyaltySplitter.sol\";\n\ninterface IFallbackRegistry {\n /**\n * @dev Get total recipients for token fees. Note that recipient bps is of gross amount, not share of fee amount,\n * ie, recipients' BPS will not sum to 10_000, but to the total fee BPS for an order.\n */\n function getRecipients(address tokenAddress) external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IEIP2981MultiReceiverRoyaltyOverride is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, Recipient[] recipients);\n event DefaultRoyaltySet(uint16 royaltyBPS, Recipient[] recipients);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(TokenRoyaltyConfig[] calldata royalties) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty configuration. Will be used if no token specific configuration is set\n */\n function setDefaultRoyalty(uint16 bps, Recipient[] calldata recipients) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyEngineV1.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport { ERC165, IERC165 } from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { AddressUpgradeable } from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport { SuperRareContracts } from \"./libraries/SuperRareContracts.sol\";\n\nimport { IManifold } from \"./specs/IManifold.sol\";\nimport { IRaribleV1, IRaribleV2 } from \"./specs/IRarible.sol\";\nimport { IFoundation } from \"./specs/IFoundation.sol\";\nimport { ISuperRareRegistry } from \"./specs/ISuperRare.sol\";\nimport { IEIP2981 } from \"./specs/IEIP2981.sol\";\nimport { IZoraOverride } from \"./specs/IZoraOverride.sol\";\nimport { IArtBlocksOverride } from \"./specs/IArtBlocksOverride.sol\";\nimport { IKODAV2Override } from \"./specs/IKODAV2Override.sol\";\nimport { IRoyaltyEngineV1 } from \"./IRoyaltyEngineV1.sol\";\nimport { IRoyaltyRegistry } from \"./IRoyaltyRegistry.sol\";\nimport { IRoyaltySplitter, Recipient } from \"./overrides/IRoyaltySplitter.sol\";\nimport { IFallbackRegistry } from \"./overrides/IFallbackRegistry.sol\";\n/**\n * @dev Engine to lookup royalty configurations\n */\n\ncontract RoyaltyEngineV1 is ERC165, OwnableUpgradeable, IRoyaltyEngineV1 {\n using AddressUpgradeable for address;\n\n // Use int16 for specs to support future spec additions\n // When we add a spec, we also decrement the NONE value\n // Anything > NONE and <= NOT_CONFIGURED is considered not configured\n int16 private constant NONE = -1;\n int16 private constant NOT_CONFIGURED = 0;\n int16 private constant MANIFOLD = 1;\n int16 private constant RARIBLEV1 = 2;\n int16 private constant RARIBLEV2 = 3;\n int16 private constant FOUNDATION = 4;\n int16 private constant EIP2981 = 5;\n int16 private constant SUPERRARE = 6;\n int16 private constant ZORA = 7;\n int16 private constant ARTBLOCKS = 8;\n int16 private constant KNOWNORIGINV2 = 9;\n int16 private constant ROYALTY_SPLITTER = 10;\n int16 private constant FALLBACK = type(int16).max;\n\n mapping(address => int16) _specCache;\n\n address public royaltyRegistry;\n IFallbackRegistry public immutable FALLBACK_REGISTRY;\n\n constructor(address fallbackRegistry) {\n FALLBACK_REGISTRY = IFallbackRegistry(fallbackRegistry);\n }\n\n function initialize(address _initialOwner, address royaltyRegistry_) public initializer {\n _transferOwnership(_initialOwner);\n require(ERC165Checker.supportsInterface(royaltyRegistry_, type(IRoyaltyRegistry).interfaceId));\n royaltyRegistry = royaltyRegistry_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override (ERC165, IERC165) returns (bool) {\n return interfaceId == type(IRoyaltyEngineV1).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Invalidate the cached spec (useful for situations where tooken royalty implementation changes to a different spec)\n */\n function invalidateCachedRoyaltySpec(address tokenAddress) public {\n address royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n delete _specCache[royaltyAddress];\n }\n\n /**\n * @dev View function to get the cached spec of a token\n */\n function getCachedRoyaltySpec(address tokenAddress) public view returns (int16) {\n address royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n return _specCache[royaltyAddress];\n }\n\n /**\n * @dev See {IRoyaltyEngineV1-getRoyalty}\n */\n function getRoyalty(address tokenAddress, uint256 tokenId, uint256 value)\n public\n override\n returns (address payable[] memory recipients, uint256[] memory amounts)\n {\n // External call to limit gas\n try this._getRoyaltyAndSpec{gas: 100000}(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients,\n uint256[] memory _amounts,\n int16 spec,\n address royaltyAddress,\n bool addToCache\n ) {\n if (addToCache) _specCache[royaltyAddress] = spec;\n return (_recipients, _amounts);\n } catch {\n revert(\"Invalid royalty amount\");\n }\n }\n\n /**\n * @dev See {IRoyaltyEngineV1-getRoyaltyView}.\n */\n function getRoyaltyView(address tokenAddress, uint256 tokenId, uint256 value)\n public\n view\n override\n returns (address payable[] memory recipients, uint256[] memory amounts)\n {\n // External call to limit gas\n try this._getRoyaltyAndSpec{gas: 100000}(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients, uint256[] memory _amounts, int16, address, bool\n ) {\n return (_recipients, _amounts);\n } catch {\n revert(\"Invalid royalty amount\");\n }\n }\n\n /**\n * @dev Get the royalty and royalty spec for a given token\n *\n * returns recipients array, amounts array, royalty spec, royalty address, whether or not to add to cache\n */\n function _getRoyaltyAndSpec(address tokenAddress, uint256 tokenId, uint256 value)\n external\n view\n returns (\n address payable[] memory recipients,\n uint256[] memory amounts,\n int16 spec,\n address royaltyAddress,\n bool addToCache\n )\n {\n require(msg.sender == address(this), \"Only Engine\");\n\n royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n spec = _specCache[royaltyAddress];\n\n if (spec <= NOT_CONFIGURED && spec > NONE) {\n // No spec configured yet, so we need to detect the spec\n addToCache = true;\n\n // SuperRare handling\n if (tokenAddress == SuperRareContracts.SUPERRARE_V1 || tokenAddress == SuperRareContracts.SUPERRARE_V2) {\n try ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).tokenCreator(tokenAddress, tokenId)\n returns (address payable creator) {\n try ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).calculateRoyaltyFee(\n tokenAddress, tokenId, value\n ) returns (uint256 amount) {\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = creator;\n amounts[0] = amount;\n return (recipients, amounts, SUPERRARE, royaltyAddress, addToCache);\n } catch { }\n } catch { }\n }\n try IEIP2981(royaltyAddress).royaltyInfo(tokenId, value) returns (address recipient, uint256 amount) {\n require(amount < value, \"Invalid royalty amount\");\n uint32 recipientSize;\n assembly {\n recipientSize := extcodesize(recipient)\n }\n if (recipientSize > 0) {\n try IRoyaltySplitter(recipient).getRecipients() returns (Recipient[] memory splitRecipients) {\n recipients = new address payable[](splitRecipients.length);\n amounts = new uint256[](splitRecipients.length);\n uint256 sum = 0;\n uint256 splitRecipientsLength = splitRecipients.length;\n for (uint256 i = 0; i < splitRecipientsLength;) {\n Recipient memory splitRecipient = splitRecipients[i];\n recipients[i] = payable(splitRecipient.recipient);\n uint256 splitAmount = splitRecipient.bps * amount / 10000;\n amounts[i] = splitAmount;\n sum += splitAmount;\n unchecked {\n ++i;\n }\n }\n // sum can be less than amount, otherwise small-value listings can break\n require(sum <= amount, \"Invalid split\");\n\n return (recipients, amounts, ROYALTY_SPLITTER, royaltyAddress, addToCache);\n } catch { }\n }\n // Supports EIP2981. Return amounts\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = payable(recipient);\n amounts[0] = amount;\n return (recipients, amounts, EIP2981, royaltyAddress, addToCache);\n } catch { }\n try IManifold(royaltyAddress).getRoyalties(tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Supports manifold interface. Compute amounts\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), MANIFOLD, royaltyAddress, addToCache);\n } catch { }\n try IRaribleV2(royaltyAddress).getRaribleV2Royalties(tokenId) returns (IRaribleV2.Part[] memory royalties) {\n // Supports rarible v2 interface. Compute amounts\n recipients = new address payable[](royalties.length);\n amounts = new uint256[](royalties.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < royalties.length; i++) {\n recipients[i] = royalties[i].account;\n amounts[i] = value * royalties[i].value / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, RARIBLEV2, royaltyAddress, addToCache);\n } catch { }\n try IRaribleV1(royaltyAddress).getFeeRecipients(tokenId) returns (address payable[] memory recipients_) {\n // Supports rarible v1 interface. Compute amounts\n recipients_ = IRaribleV1(royaltyAddress).getFeeRecipients(tokenId);\n try IRaribleV1(royaltyAddress).getFeeBps(tokenId) returns (uint256[] memory bps) {\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), RARIBLEV1, royaltyAddress, addToCache);\n } catch { }\n } catch { }\n try IFoundation(royaltyAddress).getFees(tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Supports foundation interface. Compute amounts\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), FOUNDATION, royaltyAddress, addToCache);\n } catch { }\n try IZoraOverride(royaltyAddress).convertBidShares(tokenAddress, tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Support Zora override\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), ZORA, royaltyAddress, addToCache);\n } catch { }\n try IArtBlocksOverride(royaltyAddress).getRoyalties(tokenAddress, tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Support Art Blocks override\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), ARTBLOCKS, royaltyAddress, addToCache);\n } catch { }\n try IKODAV2Override(royaltyAddress).getKODAV2RoyaltyInfo(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients, uint256[] memory _amounts\n ) {\n // Support KODA V2 override\n require(_recipients.length == _amounts.length);\n return (_recipients, _amounts, KNOWNORIGINV2, royaltyAddress, addToCache);\n } catch { }\n\n try FALLBACK_REGISTRY.getRecipients(tokenAddress) returns (Recipient[] memory _recipients) {\n uint256 recipientsLength = _recipients.length;\n if (recipientsLength > 0) {\n return _calculateFallback(_recipients, recipientsLength, value, royaltyAddress, addToCache);\n }\n } catch { }\n\n // No supported royalties configured\n return (recipients, amounts, NONE, royaltyAddress, addToCache);\n } else {\n // Spec exists, just execute the appropriate one\n addToCache = false;\n if (spec == NONE) {\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == FALLBACK) {\n Recipient[] memory _recipients = FALLBACK_REGISTRY.getRecipients(tokenAddress);\n return _calculateFallback(_recipients, _recipients.length, value, royaltyAddress, addToCache);\n } else if (spec == MANIFOLD) {\n // Manifold spec\n uint256[] memory bps;\n (recipients, bps) = IManifold(royaltyAddress).getRoyalties(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == RARIBLEV2) {\n // Rarible v2 spec\n IRaribleV2.Part[] memory royalties;\n royalties = IRaribleV2(royaltyAddress).getRaribleV2Royalties(tokenId);\n recipients = new address payable[](royalties.length);\n amounts = new uint256[](royalties.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < royalties.length; i++) {\n recipients[i] = royalties[i].account;\n amounts[i] = value * royalties[i].value / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == RARIBLEV1) {\n // Rarible v1 spec\n uint256[] memory bps;\n recipients = IRaribleV1(royaltyAddress).getFeeRecipients(tokenId);\n bps = IRaribleV1(royaltyAddress).getFeeBps(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == FOUNDATION) {\n // Foundation spec\n uint256[] memory bps;\n (recipients, bps) = IFoundation(royaltyAddress).getFees(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == EIP2981 || spec == ROYALTY_SPLITTER) {\n // EIP2981 spec\n (address recipient, uint256 amount) = IEIP2981(royaltyAddress).royaltyInfo(tokenId, value);\n require(amount < value, \"Invalid royalty amount\");\n if (spec == ROYALTY_SPLITTER) {\n Recipient[] memory splitRecipients = IRoyaltySplitter(recipient).getRecipients();\n recipients = new address payable[](splitRecipients.length);\n amounts = new uint256[](splitRecipients.length);\n uint256 sum = 0;\n uint256 splitRecipientsLength = splitRecipients.length;\n for (uint256 i = 0; i < splitRecipientsLength;) {\n Recipient memory splitRecipient = splitRecipients[i];\n recipients[i] = payable(splitRecipient.recipient);\n uint256 splitAmount = splitRecipient.bps * amount / 10000;\n amounts[i] = splitAmount;\n sum += splitAmount;\n unchecked {\n ++i;\n }\n }\n // sum can be less than amount, otherwise small-value listings can break\n require(sum <= value, \"Invalid split\");\n\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n }\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = payable(recipient);\n amounts[0] = amount;\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == SUPERRARE) {\n // SUPERRARE spec\n address payable creator =\n ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).tokenCreator(tokenAddress, tokenId);\n uint256 amount = ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).calculateRoyaltyFee(\n tokenAddress, tokenId, value\n );\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = creator;\n amounts[0] = amount;\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == ZORA) {\n // Zora spec\n uint256[] memory bps;\n (recipients, bps) = IZoraOverride(royaltyAddress).convertBidShares(tokenAddress, tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == ARTBLOCKS) {\n // Art Blocks spec\n uint256[] memory bps;\n (recipients, bps) = IArtBlocksOverride(royaltyAddress).getRoyalties(tokenAddress, tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == KNOWNORIGINV2) {\n // KnownOrigin.io V2 spec (V3 falls under EIP2981)\n (recipients, amounts) =\n IKODAV2Override(royaltyAddress).getKODAV2RoyaltyInfo(tokenAddress, tokenId, value);\n require(recipients.length == amounts.length);\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n }\n }\n }\n\n function _calculateFallback(\n Recipient[] memory _recipients,\n uint256 recipientsLength,\n uint256 value,\n address royaltyAddress,\n bool addToCache\n )\n internal\n pure\n returns (\n address payable[] memory recipients,\n uint256[] memory amounts,\n int16 spec,\n address _royaltyAddress,\n bool _addToCache\n )\n {\n recipients = new address payable[](recipientsLength);\n amounts = new uint256[](recipientsLength);\n uint256 totalAmount;\n for (uint256 i = 0; i < recipientsLength;) {\n Recipient memory recipient = _recipients[i];\n recipients[i] = payable(recipient.recipient);\n uint256 amount = value * recipient.bps / 10_000;\n amounts[i] = amount;\n totalAmount += amount;\n unchecked {\n ++i;\n }\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, FALLBACK, royaltyAddress, addToCache);\n }\n\n /**\n * Compute royalty amounts\n */\n function _computeAmounts(uint256 value, uint256[] memory bps) private pure returns (uint256[] memory amounts) {\n amounts = new uint256[](bps.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < bps.length; i++) {\n amounts[i] = value * bps[i] / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return amounts;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\"; \nimport \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@manifoldxyz/libraries-solidity/contracts/access/IAdminControl.sol\";\n\nimport \"./IRoyaltyRegistry.sol\";\nimport \"./specs/INiftyGateway.sol\";\nimport \"./specs/IFoundation.sol\";\nimport \"./specs/IDigitalax.sol\";\nimport \"./specs/IArtBlocks.sol\";\n\n/**\n * @dev Registry to lookup royalty configurations\n */\ncontract RoyaltyRegistry is ERC165, OwnableUpgradeable, IRoyaltyRegistry {\n using AddressUpgradeable for address;\n\n address public immutable OVERRIDE_FACTORY;\n\n /**\n * @notice Constructor arg allows efficient lookup of override factory for single-tx overrides.\n * However, this means the RoyaltyRegistry will need to be upgraded if the override factory is changed.\n */\n constructor(address overrideFactory) {\n OVERRIDE_FACTORY = overrideFactory;\n }\n\n // Override addresses\n mapping(address => address) private _overrides;\n mapping(address => address) private _overrideLookupToTokenContract;\n\n function initialize(address _initialOwner) public initializer {\n _transferOwnership(_initialOwner);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override (ERC165, IERC165) returns (bool) {\n return interfaceId == type(IRoyaltyRegistry).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IRegistry-getRoyaltyLookupAddress}.\n */\n function getRoyaltyLookupAddress(address tokenAddress) external view override returns (address) {\n address override_ = _overrides[tokenAddress];\n if (override_ != address(0)) {\n return override_;\n }\n return tokenAddress;\n }\n\n /**\n * @dev See {IRegistry-getOverrideTokenAddress}.\n */\n function getOverrideLookupTokenAddress(address overrideAddress) external view override returns (address) {\n return _overrideLookupToTokenContract[overrideAddress];\n }\n\n /**\n * @dev See {IRegistry-setRoyaltyLookupAddress}.\n */\n function setRoyaltyLookupAddress(address tokenAddress, address royaltyLookupAddress)\n public\n override\n returns (bool)\n {\n require(\n tokenAddress.isContract() && (royaltyLookupAddress.isContract() || royaltyLookupAddress == address(0)),\n \"Invalid input\"\n );\n require(overrideAllowed(tokenAddress), \"Permission denied\");\n // look up existing override, if any\n address existingOverride = _overrides[tokenAddress];\n if (existingOverride != address(0)) {\n // delete existing override reverse-lookup\n _overrideLookupToTokenContract[existingOverride] = address(0);\n }\n _overrideLookupToTokenContract[royaltyLookupAddress] = tokenAddress;\n // set new override and reverse-lookup\n _overrides[tokenAddress] = royaltyLookupAddress;\n\n emit RoyaltyOverride(_msgSender(), tokenAddress, royaltyLookupAddress);\n return true;\n }\n\n /**\n * @dev See {IRegistry-overrideAllowed}.\n */\n function overrideAllowed(address tokenAddress) public view override returns (bool) {\n if (owner() == _msgSender()) return true;\n\n if (\n ERC165Checker.supportsInterface(tokenAddress, type(IAdminControl).interfaceId)\n && IAdminControl(tokenAddress).isAdmin(_msgSender())\n ) {\n return true;\n }\n\n try OwnableUpgradeable(tokenAddress).owner() returns (address owner) {\n if (owner == _msgSender()) return true;\n\n if (owner.isContract()) {\n try OwnableUpgradeable(owner).owner() returns (address passThroughOwner) {\n if (passThroughOwner == _msgSender()) return true;\n } catch { }\n }\n } catch { }\n\n try IAccessControlUpgradeable(tokenAddress).hasRole(0x00, _msgSender()) returns (bool hasRole) {\n if (hasRole) return true;\n } catch { }\n\n // Nifty Gateway overrides\n try INiftyBuilderInstance(tokenAddress).niftyRegistryContract() returns (address niftyRegistry) {\n try INiftyRegistry(niftyRegistry).isValidNiftySender(_msgSender()) returns (bool valid) {\n return valid;\n } catch { }\n } catch { }\n\n // OpenSea overrides\n // Tokens already support Ownable\n\n // Foundation overrides\n try IFoundationTreasuryNode(tokenAddress).getFoundationTreasury() returns (address payable foundationTreasury) {\n try IFoundationTreasury(foundationTreasury).isAdmin(_msgSender()) returns (bool isAdmin) {\n return isAdmin;\n } catch { }\n } catch { }\n\n // DIGITALAX overrides\n try IDigitalax(tokenAddress).accessControls() returns (address externalAccessControls) {\n try IDigitalaxAccessControls(externalAccessControls).hasAdminRole(_msgSender()) returns (bool hasRole) {\n if (hasRole) return true;\n } catch { }\n } catch { }\n\n // Art Blocks overrides\n try IArtBlocks(tokenAddress).admin() returns (address admin) {\n if (admin == _msgSender()) return true;\n } catch { }\n\n // Superrare overrides\n // Tokens and registry already support Ownable\n\n // Rarible overrides\n // Tokens already support Ownable\n\n return false;\n }\n\n function _msgSender() internal view virtual override (ContextUpgradeable) returns (address) {\n if (msg.sender == OVERRIDE_FACTORY) {\n address relayedSender;\n ///@solidity memory-safe-assembly\n assembly {\n // the factory appends the original msg.sender as last the word of calldata, which we can read using\n // calldataload\n relayedSender := calldataload(sub(calldatasize(), 0x20))\n }\n return relayedSender;\n }\n // otherwise return msg.sender as normal\n return msg.sender;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IArtBlocks.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Art Blocks nfts\n */\ninterface IArtBlocks {\n // document getter function of public variable\n function admin() external view returns (address);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IArtBlocksOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * Interface for an Art Blocks override\n */\ninterface IArtBlocksOverride {\n /**\n * @dev Get royalites of a token at a given tokenAddress.\n * Returns array of receivers and basisPoints.\n *\n * bytes4(keccak256('getRoyalties(address,uint256)')) == 0x9ca7dc7a\n *\n * => 0x9ca7dc7a = 0x9ca7dc7a\n */\n function getRoyalties(address tokenAddress, uint256 tokenId)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IDigitalax.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Digitalax nfts\n */\ninterface IDigitalax {\n function accessControls() external view returns (address);\n}\n\n/**\n * @dev Digitalax Access Controls Simple\n */\ninterface IDigitalaxAccessControls {\n function hasAdminRole(address _account) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IFoundation.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IFoundation {\n /*\n * bytes4(keccak256('getFees(uint256)')) == 0xd5a06d4c\n *\n * => 0xd5a06d4c = 0xd5a06d4c\n */\n function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);\n}\n\ninterface IFoundationTreasuryNode {\n function getFoundationTreasury() external view returns (address payable);\n}\n\ninterface IFoundationTreasury {\n function isAdmin(address account) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IKODAV2Override.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/// @author: knownorigin.io\n\npragma solidity ^0.8.0;\n\ninterface IKODAV2 {\n function editionOfTokenId(uint256 _tokenId) external view returns (uint256 _editionNumber);\n\n function artistCommission(uint256 _editionNumber)\n external\n view\n returns (address _artistAccount, uint256 _artistCommission);\n\n function editionOptionalCommission(uint256 _editionNumber)\n external\n view\n returns (uint256 _rate, address _recipient);\n}\n\ninterface IKODAV2Override {\n /// @notice Emitted when the royalties fee changes\n event CreatorRoyaltiesFeeUpdated(uint256 _oldCreatorRoyaltiesFee, uint256 _newCreatorRoyaltiesFee);\n\n /// @notice For the given KO NFT and token ID, return the addresses and the amounts to pay\n function getKODAV2RoyaltyInfo(address _tokenAddress, uint256 _id, uint256 _amount)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n\n /// @notice Allows the owner() to update the creator royalties\n function updateCreatorRoyalties(uint256 _creatorRoyaltiesFee) external;\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IManifold.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\n/**\n * @dev Royalty interface for creator core classes\n */\ninterface IManifold {\n /**\n * @dev Get royalites of a token. Returns list of receivers and basisPoints\n *\n * bytes4(keccak256('getRoyalties(uint256)')) == 0xbb3bafd6\n *\n * => 0xbb3bafd6 = 0xbb3bafd6\n */\n function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/INiftyGateway.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Nifty builder instance\n */\ninterface INiftyBuilderInstance {\n function niftyRegistryContract() external view returns (address);\n}\n\n/**\n * @dev Nifty registry\n */\ninterface INiftyRegistry {\n /**\n * @dev function to see if sending key is valid\n */\n function isValidNiftySender(address sending_key) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IRarible.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IRaribleV1 {\n /*\n * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f\n * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb\n *\n * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584\n */\n function getFeeBps(uint256 id) external view returns (uint256[] memory);\n function getFeeRecipients(uint256 id) external view returns (address payable[] memory);\n}\n\ninterface IRaribleV2 {\n /*\n * bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca\n */\n struct Part {\n address payable account;\n uint96 value;\n }\n\n function getRaribleV2Royalties(uint256 id) external view returns (Part[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/ISuperRare.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface ISuperRareRegistry {\n /**\n * @dev Get the royalty fee percentage for a specific ERC721 contract.\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n * @return uint8 wei royalty fee.\n */\n function getERC721TokenRoyaltyPercentage(address _contractAddress, uint256 _tokenId)\n external\n view\n returns (uint8);\n\n /**\n * @dev Utililty function to calculate the royalty fee for a token.\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n * @param _amount uint256 wei amount.\n * @return uint256 wei fee.\n */\n function calculateRoyaltyFee(address _contractAddress, uint256 _tokenId, uint256 _amount)\n external\n view\n returns (uint256);\n\n /**\n * @dev Get the token creator which will receive royalties of the given token\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n */\n function tokenCreator(address _contractAddress, uint256 _tokenId) external view returns (address payable);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IZoraOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * Paired down version of the Zora Market interface\n */\ninterface IZoraMarket {\n struct ZoraDecimal {\n uint256 value;\n }\n\n struct ZoraBidShares {\n // % of sale value that goes to the _previous_ owner of the nft\n ZoraDecimal prevOwner;\n // % of sale value that goes to the original creator of the nft\n ZoraDecimal creator;\n // % of sale value that goes to the seller (current owner) of the nft\n ZoraDecimal owner;\n }\n\n function bidSharesForToken(uint256 tokenId) external view returns (ZoraBidShares memory);\n}\n\n/**\n * Paired down version of the Zora Media interface\n */\ninterface IZoraMedia {\n /**\n * Auto-generated accessors of public variables\n */\n function marketContract() external view returns (address);\n function previousTokenOwners(uint256 tokenId) external view returns (address);\n function tokenCreators(uint256 tokenId) external view returns (address);\n\n /**\n * ERC721 function\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n}\n\n/**\n * Interface for a Zora media override\n */\ninterface IZoraOverride {\n /**\n * @dev Convert bid share configuration of a Zora Media token into an array of receivers and bps values\n * Does not support prevOwner and sell-on amounts as that is specific to Zora marketplace implementation\n * and requires updates on the Zora Media and Marketplace to update the sell-on amounts/previous owner values.\n * An off-Zora marketplace sale will break the sell-on functionality.\n */\n function convertBidShares(address media, uint256 tokenId)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC721/ERC721Upgradeable.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 \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable 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 function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).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 = ERC721Upgradeable.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 = ERC721Upgradeable.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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.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(ERC721Upgradeable.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(ERC721Upgradeable.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(ERC721Upgradeable.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 IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.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 \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.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 IERC721ReceiverUpgradeable {\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-upgradeable/token/ERC721/IERC721Upgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@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/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC1155/IERC1155.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981 is IERC165 {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/IERC721.sol\";\n" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\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/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/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/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/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/ERC165Checker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface.\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&\n !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(\n address account,\n bytes4[] memory interfaceIds\n ) internal view returns (bool[] memory) {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n *\n * Some precompiled contracts will falsely indicate support for a given interface, so caution\n * should be exercised when using this function.\n *\n * Interface identification is specified in ERC-165.\n */\n function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IERC20Approve {\n function approve(address spender, uint256 amount) external returns (bool);\n\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyDistributor is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, address recipient);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address recipient);\n\n event RoyaltyRecipientSet(address splitter, address recipient);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty e. Will be used if no token specific configuration is set\n */\n function setDefaultRoyaltyBps(uint16 bps) external;\n\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/FallbackRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {FallbackRegistry} from \"@manifoldxyz/royalty-registry-solidity/contracts/FallbackRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/MockMarketplace.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981} from \"@openzeppelin/contracts/interfaces/IERC2981.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/interfaces/IERC1155.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/interfaces/IERC721.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport {IRoyaltyEngineV1} from \"@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyEngineV1.sol\";\n\ncontract MockMarketplace {\n IRoyaltyEngineV1 public royaltyEngine;\n\n constructor(address _royaltyEngine) {\n royaltyEngine = IRoyaltyEngineV1(_royaltyEngine);\n }\n\n function distributeRoyaltyEIP2981(\n uint256 erc20TokenAmount,\n IERC20 erc20Contract,\n address nftContract,\n uint256 nftId,\n address nftBuyer,\n address nftSeller,\n bool is1155\n ) external payable {\n if (msg.value == 0) {\n require(erc20TokenAmount > 0, \"erc20 token ammount can't be zero\");\n (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, erc20TokenAmount);\n erc20Contract.transferFrom(nftBuyer, royaltyReceiver, value);\n erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - value));\n } else {\n (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, msg.value);\n (bool sent, ) = royaltyReceiver.call{value: value}(\"\");\n require(sent, \"Failed to send distributeRoyaltyEIP2981Ether\");\n (bool sentToSeller, ) = nftSeller.call{value: msg.value - value}(\"\");\n require(sentToSeller, \"Failed to send to seller\");\n }\n if (is1155) {\n IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, \"0x\");\n } else {\n IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, \"0x\");\n }\n }\n\n function distributeRoyaltyRoyaltyEngine(\n uint256 erc20TokenAmount,\n IERC20 erc20Contract,\n address nftContract,\n uint256 nftId,\n address nftBuyer,\n address nftSeller,\n bool is1155\n ) external payable {\n if (msg.value == 0) {\n require(erc20TokenAmount > 0, \"erc20 token ammount can't be zero\");\n uint256 TotalRoyalty;\n (address payable[] memory recipients, uint256[] memory amounts) =\n royaltyEngine.getRoyalty(address(nftContract), nftId, erc20TokenAmount);\n for (uint256 i; i < recipients.length; i++) {\n erc20Contract.transferFrom(nftBuyer, recipients[i], amounts[i]);\n TotalRoyalty += amounts[i];\n }\n erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - TotalRoyalty));\n } else {\n (address payable[] memory recipients, uint256[] memory amounts) =\n royaltyEngine.getRoyalty(address(nftContract), nftId, msg.value);\n uint256 TotalRoyalty;\n for (uint256 i; i < recipients.length; i++) {\n (bool sent, ) = recipients[i].call{value: amounts[i]}(\"\");\n require(sent, \"Failed to send Ether\");\n TotalRoyalty += amounts[i];\n }\n (bool sentToSeller, ) = nftSeller.call{value: msg.value - TotalRoyalty}(\"\");\n require(sentToSeller, \"Failed to send to seller\");\n }\n if (is1155) {\n IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, \"0x\");\n } else {\n IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, \"0x\");\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyEngineV1} from \"@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyEngineV1.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyRegistry} from \"@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/SingleReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {RoyaltyDistributor} from \"../RoyaltyDistributor.sol\";\n\ncontract SingleReceiver is ERC1155Upgradeable, RoyaltyDistributor {\n /// @notice initiliaze to be called by the proxy\n /// @dev would run once.\n /// @param _manager, the address of the Manager contract for common royalty recipient\n function initialize(address _manager) external initializer {\n __RoyaltyDistributor_init(_manager);\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC1155Upgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return ERC1155Upgradeable.supportsInterface(interfaceId) || RoyaltyDistributor.supportsInterface(interfaceId);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {MultiRoyaltyDistributor} from \"../MultiRoyaltyDistributor.sol\";\n\n/// @title Test ERC1155 contract\n/// @dev Made to test splitter deployment for each creator\n/// Creator could change his royalty receiving Wallet for his splitter through setRoyaltyRecipient function\ncontract TestERC1155 is ERC1155Upgradeable, OwnableUpgradeable, MultiRoyaltyDistributor {\n /// @notice initiliaze to be called by the proxy\n /// @dev would run once.\n /// @param defaultBps default erc2981 royalty bps.(base 10000)\n /// @param defaultRecipient the default recipient of erv2981 royalty\n /// @param _manager, the address of the Manager contract for common royalty recipient\n function initialize(\n uint16 defaultBps,\n address payable defaultRecipient,\n address _manager\n ) external initializer {\n __MultiRoyaltyDistributor_init(defaultRecipient, defaultBps, _manager);\n __Ownable_init();\n }\n\n /// @notice function to mint a single ERC1155 token\n /// @param to address of the token owner\n /// @param id of the token\n /// @param amount of the token to be minted\n /// @param royaltyRecipient the royalty recipient for the creator\n /// @param data for miniting\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n address payable royaltyRecipient,\n bytes memory data\n ) external {\n _mint(to, id, amount, data);\n _setTokenRoyalties(id, _defaultRoyaltyBPS, royaltyRecipient, msg.sender);\n }\n\n /// @notice function to mint a batch ERC1155 token\n /// @param to address of the token owner\n /// @param ids array of ids the tokens\n /// @param amounts array of the amounts of tokens to be minted.\n /// @param royaltyRecipient the royalty recipient for the creator\n /// @param data for miniting\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n address payable royaltyRecipient,\n bytes memory data\n ) external {\n _mintBatch(to, ids, amounts, data);\n for (uint256 i; i < ids.length; i++) {\n _setTokenRoyalties(ids[i], _defaultRoyaltyBPS, royaltyRecipient, msg.sender);\n }\n }\n\n /// @notice EIP 165 interface funtion\n /// @dev used to check interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(MultiRoyaltyDistributor, ERC1155Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /// @notice Not in our use case\n /// @dev Explain to a developer any extra details\n /// @param tokenId a parameter just like in doxygen (must be followed by parameter name)\n /// @param royaltyBPS should be defult of use case.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external override onlyOwner {\n _setTokenRoyalties(tokenId, royaltyBPS, recipient, creator);\n }\n\n /// @notice sets default royalty bps for EIP2981\n /// @dev only owner can call.\n /// @param bps royalty bps base 10000\n function setDefaultRoyaltyBps(uint16 bps) external override onlyOwner {\n _setDefaultRoyaltyBps(bps);\n }\n\n /// @notice sets default royalty receiver for EIP2981\n /// @dev only owner can call.\n /// @param defaultReceiver address of default royalty recipient.\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external onlyOwner {\n _setDefaultRoyaltyReceiver(defaultReceiver);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC20.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n/* solhint-disable-next-line no-empty-blocks*/\n\npragma solidity ^0.8.0;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n /* solhint-disable-next-line no-empty-blocks*/\n constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {MultiRoyaltyDistributor} from \"../MultiRoyaltyDistributor.sol\";\n\ncontract TestERC721 is ERC721Upgradeable, OwnableUpgradeable, MultiRoyaltyDistributor {\n /// @notice initiliaze to be called by the proxy\n /// @dev would run once.\n /// @param defaultBps default erc2981 royalty bps.(base 10000)\n /// @param defaultRecipient the default recipient of erv2981 royalty\n /// @param _manager, the address of the Manager contract for common royalty recipient\n function initialize(\n uint16 defaultBps,\n address payable defaultRecipient,\n address _manager\n ) external initializer {\n __MultiRoyaltyDistributor_init(defaultRecipient, defaultBps, _manager);\n __Ownable_init();\n }\n\n /// @notice function to mint a single ERC721 token\n /// @param to address of the token owner\n /// @param id of the token\n /// @param royaltyRecipient the royalty recipient for the creator\n function mint(\n address to,\n uint256 id,\n address payable royaltyRecipient\n ) external {\n _mint(to, id);\n _setTokenRoyalties(id, _defaultRoyaltyBPS, royaltyRecipient, msg.sender);\n }\n\n /// @notice function to mint a batch ERC721 token\n /// @param to address of the token owner\n /// @param ids array of ids the tokens\n /// @param royaltyRecipient the royalty recipient for the creator\n function mintBatch(\n address to,\n uint256[] memory ids,\n address payable royaltyRecipient\n ) external {\n for (uint256 i; i < ids.length; i++) {\n _mint(to, ids[i]);\n _setTokenRoyalties(ids[i], _defaultRoyaltyBPS, royaltyRecipient, msg.sender);\n }\n }\n\n /// @notice EIP 165 interface funtion\n /// @dev used to check interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(MultiRoyaltyDistributor, ERC721Upgradeable)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /// @notice Not in our use case\n /// @dev Explain to a developer any extra details\n /// @param tokenId a parameter just like in doxygen (must be followed by parameter name)\n /// @param royaltyBPS should be defult of use case.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external override onlyOwner {\n _setTokenRoyalties(tokenId, royaltyBPS, recipient, creator);\n }\n\n /// @notice sets default royalty bps for EIP2981\n /// @dev only owner can call.\n /// @param bps royalty bps base 10000\n function setDefaultRoyaltyBps(uint16 bps) external override onlyOwner {\n _setDefaultRoyaltyBps(bps);\n }\n\n /// @notice sets default royalty receiver for EIP2981\n /// @dev only owner can call.\n /// @param defaultReceiver address of default royalty recipient.\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external onlyOwner {\n _setDefaultRoyaltyReceiver(defaultReceiver);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\nimport {\n IEIP2981MultiReceiverRoyaltyOverride\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol\";\nimport {IMultiRoyaltyDistributor} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributer\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributer contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to slip its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public _defaultRoyaltyBPS;\n address payable public _defaultRoyaltyReceiver;\n address public royaltyManager;\n\n mapping(uint256 => address payable) public _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n function __MultiRoyaltyDistributor_init(\n address payable defaultRecipient,\n uint16 defaultBps,\n address _royaltyManager\n ) internal {\n _defaultRoyaltyReceiver = defaultRecipient;\n _defaultRoyaltyBPS = defaultBps;\n royaltyManager = _royaltyManager;\n }\n\n /// @notice EIP 165 interface function\n /// @dev used to check the interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IEIP2981MultiReceiverRoyaltyOverride).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param royaltyBPS the bps of for EIP2981 royalty\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) internal {\n require(royaltyBPS < TOTAL_BASIS_POINTS, \"Invalid bps\");\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n _tokenRoyaltiesSplitter[tokenId] = creatorSplitterAddress;\n _tokensWithRoyalties.push(tokenId);\n emit TokenRoyaltySet(tokenId, royaltyBPS, recipient);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty\n /// @param bps the new default royalty in BPS to be set\n function _setDefaultRoyaltyBps(uint16 bps) internal {\n require(bps < TOTAL_BASIS_POINTS, \"Invalid bps\");\n _defaultRoyaltyBPS = bps;\n emit DefaultRoyaltyBpsSet(bps);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty receiver\n /// @param defaultReceiver is the new default royalty receiver in BPS to be set\n function _setDefaultRoyaltyReceiver(address payable defaultReceiver) internal {\n require(defaultReceiver != address(0), \"Default receiver can't be zero\");\n _defaultRoyaltyReceiver = defaultReceiver;\n emit DefaultRoyaltyReceiverSet(defaultReceiver);\n }\n\n /// @notice Returns royalty receivers and their split of royalty for each token\n /// @return royaltyConfigs receivers and their split array as long as the number of tokens.\n function getTokenRoyalties() external view override returns (TokenRoyaltyConfig[] memory royaltyConfigs) {\n royaltyConfigs = new TokenRoyaltyConfig[](_tokensWithRoyalties.length);\n for (uint256 i; i < _tokensWithRoyalties.length; ++i) {\n TokenRoyaltyConfig memory royaltyConfig;\n uint256 tokenId = _tokensWithRoyalties[i];\n address splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n royaltyConfig.recipients = IRoyaltySplitter(splitterAddress).getRecipients();\n }\n royaltyConfig.tokenId = tokenId;\n royaltyConfigs[i] = royaltyConfig;\n }\n }\n\n /// @notice Returns default royalty bps and the default recipient following EIP2981\n /// @dev In this contract there is only one default recipient so its split is 100 percent or 10000 points.\n /// @return bps the royalty percentage in BPS\n /// @return recipients The default recipients with their share of the royalty\n function getDefaultRoyalty() external view override returns (uint16 bps, Recipient[] memory recipients) {\n recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return (_defaultRoyaltyBPS, recipients);\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return address the royalty receiver\n /// @return value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value) public view override returns (address, uint256) {\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return addresses of royalty recipient of the token.\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n Recipient[] memory defaultRecipient = new Recipient[](1);\n defaultRecipient[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return defaultRecipient;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public _creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[msg.sender];\n require(creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(creatorSplitterAddress)._recipient();\n require(_recipient != recipient, \"Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set common recipient to zero address\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n recipient = Recipient({recipient: commonRecipient, bps: commonSplit});\n return recipient;\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress deployed for a creator\n function deploySplitter(address creator, address payable recipient) external returns (address payable) {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n _creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable) {\n return _creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @return commonRecipient\n /// @return royaltySplit\n function getRoyaltyInfo() external view returns (address, uint16) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is Initializable, OwnableUpgradeable, IRoyaltySplitter, ERC165Upgradeable {\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n uint256 internal constant IERC20_APPROVE_SELECTOR =\n 0x095ea7b300000000000000000000000000000000000000000000000000000000;\n uint256 internal constant SELECTOR_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000;\n\n address payable public _recipient;\n IRoyaltyManager public _royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipient the wallet of the creator when the contract is deployed\n /// @param royaltyManager the address of the royalty manager contract.\n function initialize(address payable recipient, address royaltyManager) public initializer {\n __Ownable_init();\n _royaltyManager = IRoyaltyManager(royaltyManager);\n _recipient = recipient;\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n _setRecipients(recipients);\n }\n\n function _setRecipients(Recipient[] calldata recipients) private {\n delete _recipient;\n require(recipients.length == 1, \"Invalid recipents length\");\n _recipient = recipients[0].recipient;\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients of royalty through this splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory recipients = new Recipient[](2);\n recipients[0].recipient = _recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() public {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n amountToSend = (value * recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) public {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n bool success;\n (success, amountToSend) = balance.tryMul(recipient.bps);\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n try erc20Contract.transfer(recipient.recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), recipient.recipient, amountToSend);\n } catch {\n return false;\n }\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n try erc20Contract.transfer(_recipients[0].recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n } catch {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice made for unexpected scenarios when assets are sent to this contact such that they could be recovered.\n /// @dev first attempts to split ERC20 tokens.\n /// @param target target of the call\n /// @param callData for the call.\n function proxyCall(address payable target, bytes calldata callData) external {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n require(\n !callData.startsWith(IERC20Approve.approve.selector) &&\n !callData.startsWith(IERC20Approve.increaseAllowance.selector),\n \"Split: ERC20 tokens must be split\"\n );\n /* solhint-disable-next-line no-empty-blocks*/\n try this.splitERC20Tokens(IERC20(target)) {} catch {}\n target.functionCall(callData);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/a7dad225e4948fd90c6be2fd4b947044.json b/packages/deploy/deployments/mumbai/solcInputs/a7dad225e4948fd90c6be2fd4b947044.json new file mode 100644 index 0000000000..40fa91a312 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/a7dad225e4948fd90c6be2fd4b947044.json @@ -0,0 +1,212 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\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/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/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/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/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" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ITokenUtils, IRoyaltyUGC} from \"./interfaces/ITokenUtils.sol\";\n\n/// @title Asset\n/// @author The Sandbox\n/// @notice ERC1155 asset token contract\n/// @notice Minting and burning tokens is only allowed through separate authorized contracts\n/// @dev This contract is final and should not be inherited\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771HandlerUpgradeable,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor,\n ITokenUtils\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param forwarder The address of the trusted forwarder\n /// @param assetAdmin The address of the asset admin\n /// @param baseUri The base URI for the token metadata\n /// @param commonSubscription The address of the operator filter subscription\n /// @param _manager The address of the royalty manager\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_init(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(_manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n /// @param metadataHash The metadata hash of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n /// @param metadataHashes The metadata hashes of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: 1-Array mismatch\");\n require(ids.length == amounts.length, \"Asset: 2-Array mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory tokenURI)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @notice returns the tokenId associated with provided metadata hash\n /// @param metadataHash The metadata hash to get tokenId for\n /// @return tokenId the tokenId associated with the metadata hash\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256 tokenId) {\n return hashUsed[metadataHash];\n }\n\n /// @notice sets the metadata hash for a given tokenId\n /// @param tokenId The tokenId to set metadata hash for\n /// @param metadataHash The metadata hash to set\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: Hash already used\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: Zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return supported `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool supported)\n {\n return id == type(IRoyaltyUGC).interfaceId || super.supportsInterface(id);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata msgData)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data additional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data additional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\n require(from == _msgSender() || isApprovedForAll(from, _msgSender()), \"Asset: Transfer error\");\n _safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creator of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, recipient, creator);\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return revealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool revealed) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16 creatorNonce) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16 revealNonce) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool bridged) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n /// @notice This function is used to register Asset contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Asset: Zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets the operator filter registry address\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Asset: Zero address\");\n OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is\n IAssetCreate,\n Initializable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable,\n AccessControlUpgradeable,\n PausableUpgradeable\n{\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _name The name of the contract (for EIP712)\n /// @param _version The version of the contract (for EIP712)\n /// @param _assetContract The address of the asset contract\n /// @param _catalystContract The address of the catalyst contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n /// @param _defaultAdmin The address of the default admin\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n __Pausable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param revealed Whether the asset is revealed or not\n /// @param metadataHash The metadata hash of the asset to mint\n /// @param creator The address of the creator\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external whenNotPaused {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"AssetCreate: Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param revealed Whether the assets are revealed or not\n /// @param metadataHashes The metadata hashes of the assets to mint\n /// @param creator The address of the creator\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external whenNotPaused {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"AssetCreate: Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"AssetCreate: Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"AssetCreate: Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"AssetCreate: Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint,\n /// @param creator The address of the creator\n function createSpecialAsset(\n bytes memory signature,\n uint256 amount,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) whenNotPaused {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash)\n ),\n \"AssetCreate: Invalid signature\"\n );\n\n uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, 0, amount, metadataHash, true);\n }\n\n /// @notice Pause the contracts mint and burn functions\n function pause() external onlyRole(PAUSER_ROLE) {\n _pause();\n }\n\n /// @notice Unpause the contracts mint and burn functions\n function unpause() external onlyRole(PAUSER_ROLE) {\n _unpause();\n }\n\n /// @notice Get the asset contract address\n /// @return assetContractAddress The asset contract address\n function getAssetContract() external view returns (address assetContractAddress) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return catalystContractAddress The catalyst contract address\n function getCatalystContract() external view returns (address catalystContractAddress) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return authValidatorAddress The auth validator address\n function getAuthValidator() external view returns (address authValidatorAddress) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param nonce The nonce of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param revealed Whether the asset is revealed or not\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param nonce The nonce of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param revealed Whether the assets are revealed or not\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetCreate: Zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n\n uint256[45] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {PausableUpgradeable} from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {IAssetReveal} from \"./interfaces/IAssetReveal.sol\";\n\n/// @title AssetReveal\n/// @author The Sandbox\n/// @notice Contract for burning and revealing assets\ncontract AssetReveal is\n IAssetReveal,\n Initializable,\n AccessControlUpgradeable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable,\n PausableUpgradeable\n{\n using TokenIdUtils for uint256;\n IAsset private assetContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator to asset id to asset's reveal nonce\n mapping(address => mapping(uint256 => uint16)) internal revealIds;\n\n // mapping for showing whether a revealHash has been used\n // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting\n mapping(bytes32 => bool) internal revealHashesUsed;\n\n // allowance list for tier to be revealed in a single transaction\n mapping(uint8 => bool) internal tierInstantRevealAllowed;\n\n bytes32 public constant PAUSER_ROLE = keccak256(\"PAUSER_ROLE\");\n\n bytes32 public constant REVEAL_TYPEHASH =\n keccak256(\n \"Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n bytes32 public constant BATCH_REVEAL_TYPEHASH =\n keccak256(\n \"BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)\"\n );\n bytes32 public constant INSTANT_REVEAL_TYPEHASH =\n keccak256(\n \"InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n __Pausable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Reveal an asset to view its abilities and enhancements\n /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId\n /// @param tokenId the tokenId of id idasset to reveal\n /// @param amount the amount of tokens to reveal\n function revealBurn(uint256 tokenId, uint256 amount) external whenNotPaused {\n _burnAsset(tokenId, amount);\n emit AssetRevealBurn(_msgSender(), tokenId, amount);\n }\n\n /// @notice Burn multiple assets to be able to reveal them later\n /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately\n /// @param tokenIds the tokenIds of the assets to burn\n /// @param amounts the amounts of the assets to burn\n function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external whenNotPaused {\n _burnAssetBatch(tokenIds, amounts);\n emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for revealed asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function revealMint(\n bytes memory signature,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external whenNotPaused {\n require(amounts.length == metadataHashes.length, \"AssetReveal: 1-Array mismatch\");\n require(amounts.length == revealHashes.length, \"AssetReveal: 2-Array mismatch\");\n require(\n authValidator.verify(\n signature,\n _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid signature\"\n );\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Mint multiple assets with revealed abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenIds The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\n function revealBatchMint(\n bytes calldata signature,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) external whenNotPaused {\n require(prevTokenIds.length == amounts.length, \"AssetReveal: 1-Array mismatch\");\n require(amounts.length == metadataHashes.length, \"AssetReveal: 2-Array mismatch\");\n require(prevTokenIds.length == revealHashes.length, \"AssetReveal: 3-Array mismatch\");\n require(\n authValidator.verify(\n signature,\n _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid signature\"\n );\n uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length);\n for (uint256 i = 0; i < prevTokenIds.length; i++) {\n newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]);\n }\n emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction\n /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\n /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param burnAmount The amount of assets to burn\n /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function burnAndReveal(\n bytes memory signature,\n uint256 prevTokenId,\n uint256 burnAmount,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external whenNotPaused {\n require(amounts.length == metadataHashes.length, \"AssetReveal: 1-Array mismatch\");\n require(amounts.length == revealHashes.length, \"AssetReveal: 2-Array mismatch\");\n uint8 tier = prevTokenId.getTier();\n require(tierInstantRevealAllowed[tier], \"AssetReveal: Not allowed\");\n require(\n authValidator.verify(\n signature,\n _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid signature\"\n );\n _burnAsset(prevTokenId, burnAmount);\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Generate new tokenIds for revealed assets and mint them\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param amounts The array of amounts to mint\n function _revealAsset(\n uint256 prevTokenId,\n string[] calldata metadataHashes,\n uint256[] calldata amounts,\n bytes32[] calldata revealHashes\n ) internal returns (uint256[] memory) {\n uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n require(revealHashesUsed[revealHashes[i]] == false, \"AssetReveal: Hash already used\");\n revealHashesUsed[revealHashes[i]] = true;\n }\n if (newTokenIds.length == 1) {\n assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]);\n } else {\n assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes);\n }\n return newTokenIds;\n }\n\n /// @notice Burns an asset to be able to reveal it later\n /// @param tokenId the tokenId of the asset to burn\n /// @param amount the amount of the asset to burn\n function _burnAsset(uint256 tokenId, uint256 amount) internal {\n _verifyBurnData(tokenId, amount);\n assetContract.burnFrom(_msgSender(), tokenId, amount);\n }\n\n function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal {\n require(tokenIds.length == amounts.length, \"AssetReveal: Invalid input\");\n for (uint256 i = 0; i < tokenIds.length; i++) {\n _verifyBurnData(tokenIds[i], amounts[i]);\n }\n assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts);\n }\n\n function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure {\n IAsset.AssetData memory data = tokenId.getData();\n require(!data.revealed, \"AssetReveal: Already revealed\");\n require(amount > 0, \"AssetReveal: Invalid amount\");\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The address of the recipient\n /// @param prevTokenId The unrevealed token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashInstantReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n INSTANT_REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed token\n /// @param prevTokenId The previous token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed tokens\n /// @param prevTokenIds The previous token id\n /// @param amounts The amounts of tokens to mint\n /// @param metadataHashes The arrays of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashBatchReveal(\n address recipient,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n BATCH_REVEAL_TYPEHASH,\n recipient,\n keccak256(abi.encodePacked(prevTokenIds)),\n _encodeBatchAmounts(amounts),\n _encodeBatchHashes(metadataHashes),\n _encodeBatchRevealHashes(revealHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = _encodeHashes(metadataHashes[i]);\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param revealHashes The revealHashes\n /// @return encodedRevealHashes The encoded hashes of the metadata\n function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](revealHashes.length);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i]));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the amounts of the tokens for signature verification\n /// @param amounts The amounts of the tokens\n /// @return encodedAmounts The encoded amounts of the tokens\n function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) {\n bytes32[] memory encodedAmounts = new bytes32[](amounts.length);\n for (uint256 i = 0; i < amounts.length; i++) {\n encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i]));\n }\n return keccak256(abi.encodePacked(encodedAmounts));\n }\n\n /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't\n /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed\n /// @param metadataHashes The hashes of the metadata\n /// @param prevTokenId The previous token id from which the assets are revealed\n /// @return tokenIds The array of tokenIds to mint\n function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId)\n internal\n returns (uint256[] memory tokenIds)\n {\n IAsset.AssetData memory data = prevTokenId.getData();\n require(!data.revealed, \"AssetReveal: Already revealed\");\n uint256[] memory tokenIdArray = new uint256[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]);\n if (tokenId == 0) {\n uint16 revealNonce = ++revealIds[data.creator][prevTokenId];\n tokenId = TokenIdUtils.generateTokenId(\n data.creator,\n data.tier,\n data.creatorNonce,\n revealNonce,\n data.bridged\n );\n }\n tokenIdArray[i] = tokenId;\n }\n return tokenIdArray;\n }\n\n /// @notice Get the status of a revealHash\n /// @return hashUsed Boolean representing whether the hash has been used\n function revealHashUsed(bytes32 revealHash) external view returns (bool hashUsed) {\n return revealHashesUsed[revealHash];\n }\n\n /// @notice Get the asset contract address\n /// @return assetContractAddres The asset contract address\n function getAssetContract() external view returns (address assetContractAddres) {\n return address(assetContract);\n }\n\n /// @notice Get the auth validator address\n /// @return authValidatorContractAddress The auth validator address\n function getAuthValidator() external view returns (address authValidatorContractAddress) {\n return address(authValidator);\n }\n\n /// @notice Set permission for instant reveal for a given tier\n /// @param tier the tier to set the permission for\n /// @param allowed allow or disallow instant reveal for the given tier\n function setTierInstantRevealAllowed(uint8 tier, bool allowed) external onlyRole(DEFAULT_ADMIN_ROLE) {\n tierInstantRevealAllowed[tier] = allowed;\n }\n\n /// @notice Get permission for instant reveal for a given tier\n /// @param tier The tier to check\n /// @return instantRevealAllowed Boolean representing whether instant reveal is allowed for the given tier\n function getTierInstantRevealAllowed(uint8 tier) external view returns (bool instantRevealAllowed) {\n return tierInstantRevealAllowed[tier];\n }\n\n /// @notice Pause the contracts mint and burn functions\n function pause() external onlyRole(PAUSER_ROLE) {\n _pause();\n }\n\n /// @notice Unpause the contracts mint and burn functions\n function unpause() external onlyRole(PAUSER_ROLE) {\n _unpause();\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: Zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: No signer\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n\n /// @notice Prevents the DEFAULT_ADMIN_ROLE from being renounced\n /// @dev This function overrides the default renounceRole function to prevent the DEFAULT_ADMIN_ROLE from being renounced\n /// @param role Role to renounce\n /// @param account Account to renounce the role for\n function renounceRole(bytes32 role, address account) public override {\n require(role != DEFAULT_ADMIN_ROLE, \"AuthSuperValidator: cant renounce admin role\");\n super.renounceRole(role, account);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice This contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771HandlerUpgradeable,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) external initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: URI empty\");\n require(_trustedForwarder != address(0), \"Catalyst: 1-Zero address\");\n require(_subscription != address(0), \"Catalyst: 2-Zero address\");\n require(_defaultAdmin != address(0), \"Catalyst: 3-Zero address\");\n require(_defaultMinter != address(0), \"Catalyst: 4-Zero address\");\n require(_royaltyManager != address(0), \"Catalyst: 5-Zero address\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_init(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID cant be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The IPFS content identifiers for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID cant be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: Zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: Metadata hash empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: URI empty\");\n _setBaseURI(baseURI);\n emit BaseURISet(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n\n /// @dev Sets `baseURI` as the `_baseURI` for all tokens\n function _setBaseURI(string memory baseURI) internal virtual override {\n super._setBaseURI(baseURI);\n emit BaseURISet(baseURI);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data additional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data additional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `interfaceId`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of OpenSea. Can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Catalyst: Zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Catalyst: Zero address\");\n OperatorFiltererUpgradeable._setOperatorFilterRegistry(registry);\n emit OperatorRegistrySet(registry);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @title Asset interface\n/// @author The Sandbox\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n /// @param metadataHash The metadata hash of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n /// @param metadataHashes The metadata hashes of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice returns the tokenId associated with provided metadata hash\n /// @param metadataHash The metadata hash to get tokenId for\n /// @return tokenId the tokenId associated with the metadata hash\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256 tokenId);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @title AssetCreate interface\n/// @author The Sandbox\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @title AssetReveal interface\n/// @author The Sandbox\ninterface IAssetReveal {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetRevealBurn(address indexed revealer, uint256 unrevealedTokenId, uint256 amount);\n event AssetRevealBatchBurn(address indexed revealer, uint256[] unrevealedTokenIds, uint256[] amounts);\n event AssetRevealMint(\n address indexed recipient,\n uint256 unrevealedTokenId,\n uint256[] amounts,\n uint256[] newTokenIds,\n bytes32[] revealHashes\n );\n event AssetRevealBatchMint(\n address indexed recipient,\n uint256[] unrevealedTokenIds,\n uint256[][] amounts,\n uint256[][] newTokenIds,\n bytes32[][] revealHashes\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n event BaseURISet(string baseURI);\n event OperatorRegistrySet(address indexed registry);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IRoyaltyUGC} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\";\n\n/// @title TokenUtils interface\n/// @author The Sandbox\ninterface ITokenUtils is IRoyaltyUGC {\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return revealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool revealed);\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16 creatorNonce);\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16 revealNonce);\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool bridged);\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\n/// @title TokenIdUtils library\n/// @author The Sandbox\n/// @notice Contains utility functions for token ids\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, tier, creator nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the creator nonce\n /// @dev The next 16 bits are for reveal nonce.\n /// @dev The last bit is for bridged boolean\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n /// @return data The asset data struct\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n _setOperatorFilterRegistry(registry);\n IOperatorFilterRegistry operatorFilterRegistry = _getOperatorFilterRegistry();\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetReveal} from \"../AssetReveal.sol\";\n\ncontract MockAssetReveal is AssetReveal {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n _setOperatorFilterRegistry(registry);\n IOperatorFilterRegistry operatorFilterRegistry = _getOperatorFilterRegistry();\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMinter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\nimport {TokenIdUtils} from \"../libraries/TokenIdUtils.sol\";\n\ncontract MockMinter {\n using TokenIdUtils for uint256;\n\n IAsset public assetContract;\n\n mapping(address => uint16) public creatorNonces;\n\n event Minted(uint256 tokenId, uint256 amount);\n\n constructor(address _assetContract) {\n assetContract = IAsset(_assetContract);\n }\n\n /// @dev Mints a specified number of unrevealed copies of specific tier\n function mintAsset(\n address recipient,\n uint256 amount,\n uint8 tier,\n bool revealed,\n string calldata metadataHash\n ) public {\n // increment nonce\n unchecked {creatorNonces[msg.sender]++;}\n // get current creator nonce\n uint16 creatorNonce = creatorNonces[msg.sender];\n uint256 tokenId = TokenIdUtils.generateTokenId(msg.sender, tier, creatorNonce, revealed ? 1 : 0, false);\n\n assetContract.mint(recipient, tokenId, amount, metadataHash);\n emit Minted(tokenId, amount);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/TokenIdUtilsWrapped.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {TokenIdUtils} from \"../libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\ncontract TokenIdUtilsWrapped {\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) public pure returns (uint256 tokenId) {\n return TokenIdUtils.generateTokenId(creator, tier, creatorNonce, revealNonce, bridged);\n }\n\n function getCreatorAddress(uint256 tokenId) public pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n function getTier(uint256 tokenId) public pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n function getCreatorNonce(uint256 tokenId) public pure returns (uint16 creatorNonce) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n function isRevealed(uint256 tokenId) public pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n function getRevealNonce(uint256 tokenId) public pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n function isBridged(uint256 tokenId) public pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n function getData(uint256 tokenId) public pure returns (IAsset.AssetData memory data) {\n return TokenIdUtils.getData(tokenId);\n }\n\n function TIER_MASK() public pure returns (uint256) {\n return TokenIdUtils.TIER_MASK;\n }\n\n function NONCE_MASK() public pure returns (uint256) {\n return TokenIdUtils.NONCE_MASK;\n }\n\n function REVEAL_NONCE_MASK() public pure returns (uint256) {\n return TokenIdUtils.REVEAL_NONCE_MASK;\n }\n\n function BRIDGED_MASK() public pure returns (uint256) {\n return TokenIdUtils.BRIDGED_MASK;\n }\n\n function TIER_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.TIER_SHIFT;\n }\n\n function NONCE_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.NONCE_SHIFT;\n }\n\n function REVEAL_NONCE_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.REVEAL_NONCE_SHIFT;\n }\n\n function BRIDGED_SHIFT() public pure returns (uint256) {\n return TokenIdUtils.BRIDGED_SHIFT;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\nabstract contract ERC2771HandlerAbstract {\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function isTrustedForwarder(address forwarder) external view returns (bool) {\n return _isTrustedForwarder(forwarder);\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual returns (address sender) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n sender = msg.sender;\n }\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual returns (bytes calldata) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n /// @dev this function must be IMPLEMENTED\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC2771HandlerAbstract} from \"./ERC2771HandlerAbstract.sol\";\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\n address private _trustedForwarder;\n\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\n /// @param oldTrustedForwarder old trusted forwarder\n /// @param newTrustedForwarder new trusted forwarder\n /// @param operator the sender of the transaction\n event TrustedForwarderSet(\n address indexed oldTrustedForwarder,\n address indexed newTrustedForwarder,\n address indexed operator\n );\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\n __ERC2771Handler_init_unchained(forwarder);\n }\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\n _setTrustedForwarder(forwarder);\n }\n\n /// @notice return the address of the trusted forwarder\n /// @return return the address of the trusted forwarder\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n /// @notice set the address of the trusted forwarder\n /// @param newForwarder the address of the new forwarder.\n function _setTrustedForwarder(address newForwarder) internal virtual {\n require(newForwarder != _trustedForwarder, \"ERC2771HandlerUpgradeable: forwarder already set\");\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\n _trustedForwarder = newForwarder;\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual override returns (address sender) {\n return super._msgSender();\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual override returns (bytes calldata) {\n return super._msgData();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IOperatorFilterRegistry\n/// @notice Interface for managing operators and filtering.\ninterface IOperatorFilterRegistry {\n ///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n /// true if supplied registrant address is not registered.\n function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed);\n\n ///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n function register(address registrant) external;\n\n ///@notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n function registerAndSubscribe(address registrant, address subscription) external;\n\n ///@notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n /// address without subscribing.\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n ///@notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n /// Note that this does not remove any filtered addresses or codeHashes.\n /// Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n function unregister(address addr) external;\n\n ///@notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n ///@notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n ///@notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n ///@notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n ///@notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n /// subscription if present.\n /// Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n /// subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n /// used.\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n ///@notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n ///@notice Get the subscription address of a given registrant, if any.\n function subscriptionOf(address addr) external returns (address registrant);\n\n ///@notice Get the set of addresses subscribed to a given registrant.\n /// Note that order is not guaranteed as updates are made.\n function subscribers(address registrant) external returns (address[] memory subscribersList);\n\n ///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n /// Note that order is not guaranteed as updates are made.\n function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress);\n\n ///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n ///@notice Returns true if operator is filtered by a given address or its subscription.\n function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered);\n\n ///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered);\n\n ///@notice Returns true if a codeHash is filtered by a given address or its subscription.\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered);\n\n ///@notice Returns a list of filtered operators for a given address or its subscription.\n function filteredOperators(address addr) external returns (address[] memory operatorList);\n\n ///@notice Returns the set of filtered codeHashes for a given address or its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList);\n\n ///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n /// its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredOperatorAt(address registrant, uint256 index) external returns (address operator);\n\n ///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n /// its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash);\n\n ///@notice Returns true if an address has registered\n function isRegistered(address addr) external returns (bool registered);\n\n ///@dev Convenience method to compute the code hash of an arbitrary contract\n function codeHashOf(address addr) external returns (bytes32 codeHash);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The Sandbox\n///@notice This contract would subscribe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's address could be set using a setter which could be implemented in inheriting contract\nabstract contract OperatorFiltererUpgradeable is Initializable, ContextUpgradeable {\n event OperatorFilterRegistrySet(address indexed registry);\n\n IOperatorFilterRegistry private operatorFilterRegistry;\n\n // solhint-disable-next-line func-name-mixedcase\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == _msgSender()) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), _msgSender())) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n /// @notice returns the operator filter registry.\n /// @return operatorFilterRegistryAddress address of operator filter registry contract.\n function getOperatorFilterRegistry() external view returns (IOperatorFilterRegistry operatorFilterRegistryAddress) {\n return _getOperatorFilterRegistry();\n }\n\n /// @notice internal method to set the operator filter registry\n /// @param registry address the registry.\n function _setOperatorFilterRegistry(address registry) internal {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n emit OperatorFilterRegistrySet(registry);\n }\n\n /// @notice internal method to get the operator filter registry.\n function _getOperatorFilterRegistry()\n internal\n view\n returns (IOperatorFilterRegistry operatorFilterRegistryAddress)\n {\n return operatorFilterRegistry;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IMultiRoyaltyRecipients} from \"./IMultiRoyaltyRecipients.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n///Multi-receiver EIP2981 reference override implementation\ninterface IMultiRoyaltyDistributor is IERC165, IMultiRoyaltyRecipients {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address indexed recipient);\n\n event RoyaltyRecipientSet(address indexed splitter, address indexed recipient);\n\n event TokenRoyaltySplitterSet(uint256 tokenId, address splitterAddress);\n\n event RoyaltyManagerSet(address indexed _royaltyManager);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n ///@notice Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n ///@param tokenId The ID of the token for which to set the royalties.\n ///@param recipient The address that will receive the royalties.\n ///@param creator The creator's address for the token.\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external;\n\n ///@notice Helper function to get all splits contracts\n ///@return an array of royalty receiver\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/// Multi-receiver EIP2981 implementation\ninterface IMultiRoyaltyRecipients is IERC165 {\n /// @dev Helper function to get all recipients\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/// @title IRoyaltyManager\n/// @notice interface for RoyaltyManager Contract\ninterface IRoyaltyManager {\n event RecipientSet(address indexed commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address indexed contractAddress);\n\n event TrustedForwarderSet(address indexed previousForwarder, address indexed newForwarder);\n\n event SplitterDeployed(address indexed creator, address indexed recipient, address splitterAddress);\n\n ///@notice sets the common recipient\n ///@param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external;\n\n ///@notice sets the common split\n ///@param commonSplit split for the common recipient\n function setSplit(uint16 commonSplit) external;\n\n ///@notice to be called by the splitters to get the common recipient and split\n ///@return recipient which has the common recipient and split\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n ///@notice returns the amount of basis points allocated to the creator\n ///@return creatorSplit the share of creator in bps\n function getCreatorSplit() external view returns (uint16 creatorSplit);\n\n ///@notice returns the commonRecipient and EIP2981 royalty split\n ///@return recipient address of common royalty recipient\n ///@return royaltySplit contract EIP2981 royalty bps\n function getRoyaltyInfo() external view returns (address payable recipient, uint16 royaltySplit);\n\n ///@notice deploys splitter for creator\n ///@param creator the address of the creator\n ///@param recipient the wallet of the recipient where they would receive their royalty\n ///@return creatorSplitterAddress splitter's address deployed for creator\n function deploySplitter(address creator, address payable recipient)\n external\n returns (address payable creatorSplitterAddress);\n\n ///@notice returns the address of splitter of a creator.\n ///@param creator the address of the creator\n ///@return creatorSplitterAddress splitter's address deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable creatorSplitterAddress);\n\n ///@notice returns the EIP2981 royalty split\n ///@param _contractAddress the address of the contract for which the royalty is required\n ///@return royaltyBps royalty bps of the contract\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\n\n ///@notice sets the trustedForwarder address to be used by the splitters\n ///@param _newForwarder is the new trusted forwarder address\n function setTrustedForwarder(address _newForwarder) external;\n\n ///@notice get the current trustedForwarder address\n ///@return trustedForwarder address of current trusted Forwarder\n function getTrustedForwarder() external view returns (address trustedForwarder);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IRoyaltyUGC\n/// @notice interface define function for managing creator of UGC (User-Generated Content)\ninterface IRoyaltyUGC {\n ///@notice Gets the address of the creator associated with a specific token.\n ///@param tokenId the Id of token to retrieve the creator address for\n ///@return creator the address of creator\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {IMultiRoyaltyDistributor, IMultiRoyaltyRecipients} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributor\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributor contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to split its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n address private royaltyManager;\n\n mapping(uint256 => address payable) private _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n // solhint-disable-next-line func-name-mixedcase\n function __MultiRoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing {\n _setRoyaltyManager(_royaltyManager);\n __ERC165_init_unchained();\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return isSupported `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool isSupported)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n interfaceId == type(IMultiRoyaltyRecipients).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param recipient royalty recipient\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) internal {\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n if (_tokenRoyaltiesSplitter[tokenId] != creatorSplitterAddress) {\n _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress);\n }\n } else {\n _tokensWithRoyalties.push(tokenId);\n _setTokenRoyaltiesSplitter(tokenId, creatorSplitterAddress);\n }\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return receiver address the royalty receiver\n /// @return royaltyAmount value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value)\n public\n view\n override\n returns (address receiver, uint256 royaltyAmount)\n {\n (address payable _defaultRoyaltyReceiver, uint16 _defaultRoyaltyBPS) =\n IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return recipients array of royalty recipients for the token\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory recipients) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n recipients = new Recipient[](1);\n recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return recipients;\n }\n\n /// @notice internal function to set the token royalty splitter\n /// @param tokenId id of token\n /// @param splitterAddress address of the splitter contract\n function _setTokenRoyaltiesSplitter(uint256 tokenId, address payable splitterAddress) internal {\n _tokenRoyaltiesSplitter[tokenId] = splitterAddress;\n emit TokenRoyaltySplitterSet(tokenId, splitterAddress);\n }\n\n /// @notice returns the address of token royalty splitter.\n /// @param tokenId is the token id for which royalty splitter should be returned.\n /// @return splitterAddress address of royalty splitter for the token\n function getTokenRoyaltiesSplitter(uint256 tokenId) external view returns (address payable splitterAddress) {\n return _tokenRoyaltiesSplitter[tokenId];\n }\n\n /// @notice returns the address of royalty manager.\n /// @return managerAddress address of royalty manager.\n function getRoyaltyManager() external view returns (address managerAddress) {\n return royaltyManager;\n }\n\n /// @notice set royalty manager address\n /// @param _royaltyManager address of royalty manager to set\n function _setRoyaltyManager(address _royaltyManager) internal {\n royaltyManager = _royaltyManager;\n emit RoyaltyManagerSet(_royaltyManager);\n }\n\n uint256[47] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n ERC165Upgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title RoyaltyDistributor\n/// @author The Sandbox\n/// @notice Contract for distributing royalties based on the ERC2981 standard.\nabstract contract RoyaltyDistributor is IERC2981Upgradeable, ERC165Upgradeable {\n event RoyaltyManagerSet(address indexed _royaltyManager);\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager private royaltyManager;\n\n // solhint-disable-next-line func-name-mixedcase\n function __RoyaltyDistributor_init(address _royaltyManager) internal onlyInitializing {\n _setRoyaltyManager(_royaltyManager);\n __ERC165_init_unchained();\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return isSupported `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool isSupported)\n {\n return (interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId));\n }\n\n /// @notice returns the royalty manager\n /// @return royaltyManagerAddress address of royalty manager contract.\n function getRoyaltyManager() external view returns (IRoyaltyManager royaltyManagerAddress) {\n return royaltyManager;\n }\n\n /// @notice set royalty manager\n /// @param _royaltyManager address of royalty manager to set\n function _setRoyaltyManager(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n emit RoyaltyManagerSet(_royaltyManager);\n }\n\n uint256[49] private __gap;\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/af7236032b56a5cadc46f21dd0482b3b.json b/packages/deploy/deployments/mumbai/solcInputs/af7236032b56a5cadc46f21dd0482b3b.json new file mode 100644 index 0000000000..703d92364e --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/af7236032b56a5cadc46f21dd0482b3b.json @@ -0,0 +1,110 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC721/ERC721Upgradeable.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 \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable 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 function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).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 = ERC721Upgradeable.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 = ERC721Upgradeable.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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.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(ERC721Upgradeable.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(ERC721Upgradeable.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(ERC721Upgradeable.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 IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.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 \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.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 IERC721ReceiverUpgradeable {\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-upgradeable/token/ERC721/IERC721Upgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@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/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" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\nabstract contract ERC2771HandlerAbstract {\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function isTrustedForwarder(address forwarder) external view returns (bool) {\n return _isTrustedForwarder(forwarder);\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual returns (address sender) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n sender = msg.sender;\n }\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual returns (bytes calldata) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n /// @dev this function must be IMPLEMENTED\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC2771HandlerAbstract} from \"./ERC2771HandlerAbstract.sol\";\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\n address private _trustedForwarder;\n\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\n /// @param oldTrustedForwarder old trusted forwarder\n /// @param newTrustedForwarder new trusted forwarder\n /// @param operator the sender of the transaction\n event TrustedForwarderSet(\n address indexed oldTrustedForwarder,\n address indexed newTrustedForwarder,\n address indexed operator\n );\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\n __ERC2771Handler_init_unchained(forwarder);\n }\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\n _setTrustedForwarder(forwarder);\n }\n\n /// @notice return the address of the trusted forwarder\n /// @return return the address of the trusted forwarder\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n /// @notice set the address of the trusted forwarder\n /// @param newForwarder the address of the new forwarder.\n function _setTrustedForwarder(address newForwarder) internal virtual {\n require(newForwarder != _trustedForwarder, \"ERC2771HandlerUpgradeable: forwarder already set\");\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\n _trustedForwarder = newForwarder;\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual override returns (address sender) {\n return super._msgSender();\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual override returns (bytes calldata) {\n return super._msgData();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title IOperatorFilterRegistry\n/// @notice Interface for managing operators and filtering.\ninterface IOperatorFilterRegistry {\n ///@notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n /// true if supplied registrant address is not registered.\n function isOperatorAllowed(address registrant, address operator) external view returns (bool isAllowed);\n\n ///@notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n function register(address registrant) external;\n\n ///@notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n function registerAndSubscribe(address registrant, address subscription) external;\n\n ///@notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n /// address without subscribing.\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n ///@notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n /// Note that this does not remove any filtered addresses or codeHashes.\n /// Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n function unregister(address addr) external;\n\n ///@notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n ///@notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n ///@notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n ///@notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n ///@notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n /// subscription if present.\n /// Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n /// subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n /// used.\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n ///@notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n ///@notice Get the subscription address of a given registrant, if any.\n function subscriptionOf(address addr) external returns (address registrant);\n\n ///@notice Get the set of addresses subscribed to a given registrant.\n /// Note that order is not guaranteed as updates are made.\n function subscribers(address registrant) external returns (address[] memory subscribersList);\n\n ///@notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n /// Note that order is not guaranteed as updates are made.\n function subscriberAt(address registrant, uint256 index) external returns (address subscriberAddress);\n\n ///@notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n ///@notice Returns true if operator is filtered by a given address or its subscription.\n function isOperatorFiltered(address registrant, address operator) external returns (bool isFiltered);\n\n ///@notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool isFiltered);\n\n ///@notice Returns true if a codeHash is filtered by a given address or its subscription.\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool isFiltered);\n\n ///@notice Returns a list of filtered operators for a given address or its subscription.\n function filteredOperators(address addr) external returns (address[] memory operatorList);\n\n ///@notice Returns the set of filtered codeHashes for a given address or its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredCodeHashes(address addr) external returns (bytes32[] memory codeHashList);\n\n ///@notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n /// its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredOperatorAt(address registrant, uint256 index) external returns (address operator);\n\n ///@notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n /// its subscription.\n /// Note that order is not guaranteed as updates are made.\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32 codeHash);\n\n ///@notice Returns true if an address has registered\n function isRegistered(address addr) external returns (bool registered);\n\n ///@dev Convenience method to compute the code hash of an arbitrary contract\n function codeHashOf(address addr) external returns (bytes32 codeHash);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/TestERC1155.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n ERC1155Upgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {OperatorFiltererUpgradeable} from \"../OperatorFiltererUpgradeable.sol\";\n\nimport {IOperatorFilterRegistry} from \"../interfaces/IOperatorFilterRegistry.sol\";\n\ncontract TestERC1155 is ERC1155Upgradeable, OperatorFiltererUpgradeable, ERC2771HandlerUpgradeable {\n function initialize(string memory uri_, address trustedForwarder) external initializer {\n __ERC1155_init(uri_);\n __ERC2771Handler_init(trustedForwarder);\n }\n\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n _setOperatorFilterRegistry(registry);\n IOperatorFilterRegistry(registry).registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for token transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n super.setApprovalForAll(operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\n super.safeTransferFrom(from, to, id, amount, data);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/TestERC721.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n ERC721Upgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport {OperatorFiltererUpgradeable} from \"../OperatorFiltererUpgradeable.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IOperatorFilterRegistry} from \"../interfaces/IOperatorFilterRegistry.sol\";\n\ncontract TestERC721 is ERC721Upgradeable, OperatorFiltererUpgradeable, ERC2771HandlerUpgradeable {\n function initialize(\n string memory name_,\n string memory symbol_,\n address trustedForwarder\n ) external initializer() {\n __ERC721_init(name_, symbol_);\n __ERC2771Handler_init(trustedForwarder);\n }\n\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n _setOperatorFilterRegistry(registry);\n IOperatorFilterRegistry(registry).registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n function mintWithoutMinterRole(address to, uint256 id) external {\n _mint(to, id);\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual override onlyAllowedOperator(from) {\n super.safeTransferFrom(from, to, id);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/UnregisteredToken.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n ERC1155Upgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OperatorFiltererUpgradeable} from \"../OperatorFiltererUpgradeable.sol\";\nimport {\n ERC2771HandlerUpgradeable\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IOperatorFilterRegistry} from \"../interfaces/IOperatorFilterRegistry.sol\";\n\ncontract UnregisteredToken is ERC1155Upgradeable, OperatorFiltererUpgradeable, ERC2771HandlerUpgradeable {\n function initialize(\n string memory uri_,\n address subscription,\n bool subscribe,\n address trustedForwarder\n ) external initializer() {\n __ERC1155_init(uri_);\n __OperatorFilterer_init(subscription, subscribe);\n __ERC2771Handler_init(trustedForwarder);\n }\n\n /// @notice sets registry\n /// @param registry address of registry\n function setRegistry(address registry) external {\n _setOperatorFilterRegistry(registry);\n }\n\n /// @notice register contract\n /// @param subscription the address of subscription\n /// @param subscribe bool representing to suscribe or not.\n function registerAndSubscribe(address subscription, bool subscribe) external {\n _registerAndSubscribe(subscription, subscribe);\n }\n\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n _setOperatorFilterRegistry(registry);\n IOperatorFilterRegistry(registry).registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n super.setApprovalForAll(operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\n super.safeTransferFrom(from, to, id, amount, data);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (address sender)\n {\n return ERC2771HandlerUpgradeable._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerUpgradeable)\n returns (bytes calldata)\n {\n return ERC2771HandlerUpgradeable._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\nimport {ContextUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The Sandbox\n///@notice This contract would subscribe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's address could be set using a setter which could be implemented in inheriting contract\nabstract contract OperatorFiltererUpgradeable is Initializable, ContextUpgradeable {\n event OperatorFilterRegistrySet(address indexed registry);\n\n IOperatorFilterRegistry private operatorFilterRegistry;\n\n // solhint-disable-next-line func-name-mixedcase\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == _msgSender()) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), _msgSender())) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n /// @notice returns the operator filter registry.\n /// @return operatorFilterRegistryAddress address of operator filter registry contract.\n function getOperatorFilterRegistry() external view returns (IOperatorFilterRegistry operatorFilterRegistryAddress) {\n return _getOperatorFilterRegistry();\n }\n\n /// @notice internal method to set the operator filter registry\n /// @param registry address the registry.\n function _setOperatorFilterRegistry(address registry) internal {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n emit OperatorFilterRegistrySet(registry);\n }\n\n /// @notice internal method to get the operator filter registry.\n function _getOperatorFilterRegistry()\n internal\n view\n returns (IOperatorFilterRegistry operatorFilterRegistryAddress)\n {\n return operatorFilterRegistry;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFilterSubscription.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/// @title OperatorFilterSubription\n/// @author The Sandbox\n/// @notice This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on OpenSea operator filter registry\ncontract OperatorFilterSubscription is Ownable {\n address public constant DEFAULT_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;\n\n // solhint-disable-next-line const-name-snakecase\n IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =\n IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);\n\n constructor() Ownable() {\n // Subscribe and copy the entries of the Default subscription list of OpenSea.\n if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {\n OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/bd10ef45797bc7e664de7280929fd385.json b/packages/deploy/deployments/mumbai/solcInputs/bd10ef45797bc7e664de7280929fd385.json new file mode 100644 index 0000000000..bb77aa2ef1 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/bd10ef45797bc7e664de7280929fd385.json @@ -0,0 +1,152 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC1155/IERC1155Upgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC721/ERC721Upgradeable.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 \"./IERC721Upgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC721MetadataUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable {\n using AddressUpgradeable for address;\n using StringsUpgradeable 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 function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC721_init_unchained(name_, symbol_);\n }\n\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IERC721MetadataUpgradeable).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 = ERC721Upgradeable.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 = ERC721Upgradeable.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 = ERC721Upgradeable.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721Upgradeable.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(ERC721Upgradeable.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(ERC721Upgradeable.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(ERC721Upgradeable.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 IERC721ReceiverUpgradeable(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.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 \"../IERC721Upgradeable.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 IERC721MetadataUpgradeable is IERC721Upgradeable {\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-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.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 IERC721ReceiverUpgradeable {\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-upgradeable/token/ERC721/IERC721Upgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@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/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/ERC1155/utils/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\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/ERC721/utils/ERC721Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Receiver.sol\";\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\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/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/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace1 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace2 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace3 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace4 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"operator-filter-registry/src/IOperatorFilterRegistry.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n OperatorFilterRegistryErrorsAndEvents\n} from \"operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol\";\n\n/**\n * @title MockOperatorFilterRegistry\n * @notice Made based on the OperatorFilterRegistry of openSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol\n * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be\n * * restricted according to the isOperatorAllowed function.\n */\ncontract MockOperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)\n /// Note that this will also be a smart contract's codehash when making calls from its constructor.\n bytes32 internal constant EOA_CODEHASH = keccak256(\"\");\n\n mapping(address => EnumerableSet.AddressSet) private _filteredOperators;\n mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;\n mapping(address => address) private _registrations;\n mapping(address => EnumerableSet.AddressSet) private _subscribers;\n\n constructor(address _defaultSubscription, address[] memory _blacklistedAddresses) {\n _registrations[_defaultSubscription] = _defaultSubscription;\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[_defaultSubscription];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[_defaultSubscription];\n for (uint256 i; i < _blacklistedAddresses.length; i++) {\n filteredOperatorsRef.add(_blacklistedAddresses[i]);\n bytes32 codeHash = _blacklistedAddresses[i].codehash;\n filteredCodeHashesRef.add(codeHash);\n }\n }\n\n /**\n * @notice Restricts method caller to the address or EIP-173 \"owner()\"\n */\n modifier onlyAddressOrOwner(address addr) {\n if (msg.sender != addr) {\n try Ownable(addr).owner() returns (address owner) {\n if (msg.sender != owner) {\n revert OnlyAddressOrOwner();\n }\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NotOwnable();\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n }\n _;\n }\n\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n * Note that this method will *revert* if an operator or its codehash is filtered with an error that is\n * more informational than a false boolean, so smart contracts that query this method for informational\n * purposes will need to wrap in a try/catch or perform a low-level staticcall in order to handle the case\n * that an operator is filtered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n EnumerableSet.AddressSet storage filteredOperatorsRef;\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef;\n\n filteredOperatorsRef = _filteredOperators[registration];\n filteredCodeHashesRef = _filteredCodeHashes[registration];\n\n if (filteredOperatorsRef.contains(operator)) {\n revert AddressFiltered(operator);\n }\n if (operator.code.length > 0) {\n bytes32 codeHash = operator.codehash;\n if (filteredCodeHashesRef.contains(codeHash)) {\n revert CodeHashFiltered(operator, codeHash);\n }\n }\n }\n return true;\n }\n\n //////////////////\n // AUTH METHODS //\n //////////////////\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external onlyAddressOrOwner(registrant) {\n if (_registrations[registrant] != address(0)) {\n revert AlreadyRegistered();\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n }\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address registrant) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = address(0);\n emit RegistrationUpdated(registrant, false);\n }\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n if (registrant == subscription) {\n revert CannotSubscribeToSelf();\n }\n address subscriptionRegistration = _registrations[subscription];\n if (subscriptionRegistration == address(0)) {\n revert NotRegistered(subscription);\n }\n if (subscriptionRegistration != subscription) {\n revert CannotSubscribeToRegistrantWithSubscription(subscription);\n }\n\n _registrations[registrant] = subscription;\n _subscribers[subscription].add(registrant);\n emit RegistrationUpdated(registrant, true);\n emit SubscriptionUpdated(registrant, subscription, true);\n }\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy)\n external\n onlyAddressOrOwner(registrant)\n {\n if (registrantToCopy == registrant) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n _copyEntries(registrant, registrantToCopy);\n }\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n\n if (!filtered) {\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n } else {\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n }\n emit OperatorUpdated(registrant, operator, filtered);\n }\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codeHash,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n\n if (!filtered) {\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n } else {\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n }\n emit CodeHashUpdated(registrant, codeHash, filtered);\n }\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n uint256 operatorsLength = operators.length;\n if (!filtered) {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n unchecked {++i;}\n }\n }\n emit OperatorsUpdated(registrant, operators, filtered);\n }\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n uint256 codeHashesLength = codeHashes.length;\n if (!filtered) {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n unchecked {++i;}\n }\n }\n emit CodeHashesUpdated(registrant, codeHashes, filtered);\n }\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {\n if (registrant == newSubscription) {\n revert CannotSubscribeToSelf();\n }\n if (newSubscription == address(0)) {\n revert CannotSubscribeToZeroAddress();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == newSubscription) {\n revert AlreadySubscribed(newSubscription);\n }\n address newSubscriptionRegistration = _registrations[newSubscription];\n if (newSubscriptionRegistration == address(0)) {\n revert NotRegistered(newSubscription);\n }\n if (newSubscriptionRegistration != newSubscription) {\n revert CannotSubscribeToRegistrantWithSubscription(newSubscription);\n }\n\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = newSubscription;\n _subscribers[newSubscription].add(registrant);\n emit SubscriptionUpdated(registrant, newSubscription, true);\n }\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == registrant) {\n revert NotSubscribed();\n }\n _subscribers[registration].remove(registrant);\n _registrations[registrant] = registrant;\n emit SubscriptionUpdated(registrant, registration, false);\n if (copyExistingEntries) {\n _copyEntries(registrant, registration);\n }\n }\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {\n if (registrant == registrantToCopy) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _copyEntries(registrant, registrantToCopy);\n }\n\n /// @dev helper to copy entries from registrantToCopy to registrant and emit events\n function _copyEntries(address registrant, address registrantToCopy) private {\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];\n uint256 filteredOperatorsLength = filteredOperatorsRef.length();\n uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();\n for (uint256 i = 0; i < filteredOperatorsLength; ) {\n address operator = filteredOperatorsRef.at(i);\n bool added = _filteredOperators[registrant].add(operator);\n if (added) {\n emit OperatorUpdated(registrant, operator, true);\n }\n unchecked {++i;}\n }\n for (uint256 i = 0; i < filteredCodeHashesLength; ) {\n bytes32 codehash = filteredCodeHashesRef.at(i);\n bool added = _filteredCodeHashes[registrant].add(codehash);\n if (added) {\n emit CodeHashUpdated(registrant, codehash, true);\n }\n unchecked {++i;}\n }\n }\n\n //////////////////\n // VIEW METHODS //\n //////////////////\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address registrant) external view returns (address subscription) {\n subscription = _registrations[registrant];\n if (subscription == address(0)) {\n revert NotRegistered(registrant);\n } else if (subscription == registrant) {\n subscription = address(0);\n }\n }\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external view returns (address[] memory) {\n return _subscribers[registrant].values();\n }\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external view returns (address) {\n return _subscribers[registrant].at(index);\n }\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].contains(operator);\n }\n return _filteredOperators[registrant].contains(operator);\n }\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {\n bytes32 codeHash = operatorWithCode.codehash;\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address registrant) external view returns (bool) {\n return _registrations[registrant] != address(0);\n }\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address registrant) external view returns (address[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].values();\n }\n return _filteredOperators[registrant].values();\n }\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].values();\n }\n return _filteredCodeHashes[registrant].values();\n }\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].at(index);\n }\n return _filteredOperators[registrant].at(index);\n }\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].at(index);\n }\n return _filteredCodeHashes[registrant].at(index);\n }\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address a) external view returns (bytes32) {\n return a.codehash;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"operator-filter-registry/src/IOperatorFilterRegistry.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\n/**\n * @title OwnedRegistrant\n * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,\n * to facilitate a subscription whose ownership can be transferred.\n */\n\ncontract MockOperatorFilterSubscription is Ownable2Step {\n address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);\n\n /// @dev The constructor that is called when the contract is being deployed.\n /// @dev This contract is based on OpenSea's OwnedRegistrant.\n /// @dev The param _localRegistry has been added to the constructor to enable local testing.\n constructor(address _owner, address _localRegistry) {\n IOperatorFilterRegistry(_localRegistry).registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);\n transferOwnership(_owner);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/TestERC1155.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OperatorFiltererUpgradeable} from \"../OperatorFiltererUpgradeable.sol\";\nimport {IOperatorFilterRegistry} from \"../interfaces/IOperatorFilterRegistry.sol\";\n\ncontract TestERC1155 is ERC1155Upgradeable, OperatorFiltererUpgradeable {\n function initialize(string memory uri_) external initializer() {\n __ERC1155_init(uri_);\n }\n\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n super.setApprovalForAll(operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\n super.safeTransferFrom(from, to, id, amount, data);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/TestERC721.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {ERC721Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\nimport {OperatorFiltererUpgradeable} from \"../OperatorFiltererUpgradeable.sol\";\nimport {IOperatorFilterRegistry} from \"../interfaces/IOperatorFilterRegistry.sol\";\n\ncontract TestERC721 is ERC721Upgradeable, OperatorFiltererUpgradeable {\n function initialize(string memory name_, string memory symbol_) external initializer() {\n __ERC721_init(name_, symbol_);\n }\n\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n function mintWithoutMinterRole(address to, uint256 id) external {\n _mint(to, id);\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id\n ) public virtual override onlyAllowedOperator(from) {\n super.safeTransferFrom(from, to, id);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFilterSubscription.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/// @title OperatorFilterSubription\n/// @author The Sandbox\n/// @notice This contract is meant to register and copy the default subscription of the OpenSea for the operator filter and our Token contract are supposed to subscribe to this contract on openSea operator filter registry\ncontract OperatorFilterSubscription is Ownable {\n address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);\n\n IOperatorFilterRegistry public constant operatorFilterRegistry =\n IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);\n\n constructor() Ownable() {\n // Subscribe and copy the entries of the Default subscription list of open sea.\n if (address(operatorFilterRegistry).code.length > 0) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);\n }\n }\n}\n" + }, + "operator-filter-registry/src/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(address registrant, address operator, bool filtered) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(address registrant, address[] calldata operators, bool filtered) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ncontract OperatorFilterRegistryErrorsAndEvents {\n /// @notice Emitted when trying to register an address that has no code.\n error CannotFilterEOAs();\n\n /// @notice Emitted when trying to add an address that is already filtered.\n error AddressAlreadyFiltered(address operator);\n\n /// @notice Emitted when trying to remove an address that is not filtered.\n error AddressNotFiltered(address operator);\n\n /// @notice Emitted when trying to add a codehash that is already filtered.\n error CodeHashAlreadyFiltered(bytes32 codeHash);\n\n /// @notice Emitted when trying to remove a codehash that is not filtered.\n error CodeHashNotFiltered(bytes32 codeHash);\n\n /// @notice Emitted when the caller is not the address or EIP-173 \"owner()\"\n error OnlyAddressOrOwner();\n\n /// @notice Emitted when the registrant is not registered.\n error NotRegistered(address registrant);\n\n /// @notice Emitted when the registrant is already registered.\n error AlreadyRegistered();\n\n /// @notice Emitted when the registrant is already subscribed.\n error AlreadySubscribed(address subscription);\n\n /// @notice Emitted when the registrant is not subscribed.\n error NotSubscribed();\n\n /// @notice Emitted when trying to update a registration where the registrant is already subscribed.\n error CannotUpdateWhileSubscribed(address subscription);\n\n /// @notice Emitted when trying to subscribe to itself.\n error CannotSubscribeToSelf();\n\n /// @notice Emitted when trying to subscribe to the zero address.\n error CannotSubscribeToZeroAddress();\n\n /// @notice Emitted when trying to register and the contract is not ownable (EIP-173 \"owner()\")\n error NotOwnable();\n\n /// @notice Emitted when an address is filtered.\n error AddressFiltered(address filtered);\n\n /// @notice Emitted when a codeHash is filtered.\n error CodeHashFiltered(address account, bytes32 codeHash);\n\n /// @notice Emited when trying to register to a registrant with a subscription.\n error CannotSubscribeToRegistrantWithSubscription(address registrant);\n\n /// @notice Emitted when trying to copy a registration from itself.\n error CannotCopyFromSelf();\n\n /// @notice Emitted when a registration is updated.\n event RegistrationUpdated(address indexed registrant, bool indexed registered);\n\n /// @notice Emitted when an operator is updated.\n event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);\n\n /// @notice Emitted when multiple operators are updated.\n event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);\n\n /// @notice Emitted when a codeHash is updated.\n event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);\n\n /// @notice Emitted when multiple codeHashes are updated.\n event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);\n\n /// @notice Emitted when a subscription is updated.\n event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/ceb274902183f5f625535381b6163583.json b/packages/deploy/deployments/mumbai/solcInputs/ceb274902183f5f625535381b6163583.json new file mode 100644 index 0000000000..d105aa02da --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/ceb274902183f5f625535381b6163583.json @@ -0,0 +1,170 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\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/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/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/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/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" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is IAssetCreate, Initializable, ERC2771Handler, EIP712Upgradeable, AccessControlUpgradeable {\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_initialize(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param metadataHashes The metadata hashes of the assets to mint\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createSpecialAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return The catalyst contract address\n function getCatalystContract() external view returns (address) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: signer not set\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771Handler,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_initialize(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return\n ERC1155Upgradeable.supportsInterface(interfaceId) ||\n AccessControlUpgradeable.supportsInterface(interfaceId) ||\n RoyaltyDistributor.supportsInterface(interfaceId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/ERC2771Handler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n/// with an initializer for proxies and a mutable forwarder\n\nabstract contract ERC2771Handler {\n address internal _trustedForwarder;\n\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/e64fd56b3bfae7f817a31de5cae19a1b.json b/packages/deploy/deployments/mumbai/solcInputs/e64fd56b3bfae7f817a31de5cae19a1b.json new file mode 100644 index 0000000000..b17d7d4a2e --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/e64fd56b3bfae7f817a31de5cae19a1b.json @@ -0,0 +1,242 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\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/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/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/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/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/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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\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" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable,\n IAccessControlUpgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable,\n IERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable,\n IERC1155MetadataURIUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ITokenUtils, IRoyaltyUGC} from \"./interfaces/ITokenUtils.sol\";\n\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771HandlerUpgradeable,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor,\n ITokenUtils\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_init(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(_manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: ids and metadataHash length mismatch\");\n require(ids.length == amounts.length, \"Asset: ids and amounts length mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {\n return hashUsed[metadataHash];\n }\n\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: not allowed to reuse metadata hash\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool)\n {\n return id == type(IRoyaltyUGC).interfaceId || super.supportsInterface(id);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\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 /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, recipient, creator);\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator) {\n return TokenIdUtils.getCreatorAddress(tokenId);\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) external pure returns (uint8 tier) {\n return TokenIdUtils.getTier(tokenId);\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isRevealed(tokenId);\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getCreatorNonce(tokenId);\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) external pure returns (uint16) {\n return TokenIdUtils.getRevealNonce(tokenId);\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) external pure returns (bool) {\n return TokenIdUtils.isBridged(tokenId);\n }\n\n /// @notice This function is used to register Asset contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Asset: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Asset: registry can't be zero address\");\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is\n IAssetCreate,\n Initializable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable,\n AccessControlUpgradeable\n{\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param metadataHashes The metadata hashes of the assets to mint\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint,\n /// @param creator The address of the creator\n function createSpecialAsset(\n bytes memory signature,\n uint256 amount,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, 0, amount, true, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId = TokenIdUtils.generateTokenId(creator, 0, ++creatorNonces[creator], 1, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, 0, amount, metadataHash, true);\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return The catalyst contract address\n function getCatalystContract() external view returns (address) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetCreate: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {IAssetReveal} from \"./interfaces/IAssetReveal.sol\";\n\n/// @title AssetReveal\n/// @author The Sandbox\n/// @notice Contract for burning and revealing assets\ncontract AssetReveal is\n IAssetReveal,\n Initializable,\n AccessControlUpgradeable,\n ERC2771HandlerUpgradeable,\n EIP712Upgradeable\n{\n using TokenIdUtils for uint256;\n IAsset private assetContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator to asset id to asset's reveal nonce\n mapping(address => mapping(uint256 => uint16)) internal revealIds;\n\n // mapping for showing whether a revealHash has been used\n // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting\n mapping(bytes32 => bool) internal revealHashesUsed;\n\n bytes32 public constant REVEAL_TYPEHASH =\n keccak256(\n \"Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n bytes32 public constant BATCH_REVEAL_TYPEHASH =\n keccak256(\n \"BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)\"\n );\n bytes32 public constant INSTANT_REVEAL_TYPEHASH =\n keccak256(\n \"InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_init(_forwarder);\n __EIP712_init(_name, _version);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Reveal an asset to view its abilities and enhancements\n /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId\n /// @param tokenId the tokenId of id idasset to reveal\n /// @param amount the amount of tokens to reveal\n function revealBurn(uint256 tokenId, uint256 amount) external {\n _burnAsset(tokenId, amount);\n emit AssetRevealBurn(_msgSender(), tokenId, amount);\n }\n\n /// @notice Burn multiple assets to be able to reveal them later\n /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately\n /// @param tokenIds the tokenIds of the assets to burn\n /// @param amounts the amounts of the assets to burn\n function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external {\n _burnAssetBatch(tokenIds, amounts);\n emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for revealed asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function revealMint(\n bytes memory signature,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealMint signature\"\n );\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Mint multiple assets with revealed abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenIds The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\n function revealBatchMint(\n bytes calldata signature,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) external {\n require(prevTokenIds.length == amounts.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid metadataHashes length\");\n require(prevTokenIds.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealBatchMint signature\"\n );\n uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length);\n for (uint256 i = 0; i < prevTokenIds.length; i++) {\n newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]);\n }\n emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction\n /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\n /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param burnAmount The amount of assets to burn\n /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function burnAndReveal(\n bytes memory signature,\n uint256 prevTokenId,\n uint256 burnAmount,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid burnAndReveal signature\"\n );\n _burnAsset(prevTokenId, burnAmount);\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Generate new tokenIds for revealed assets and mint them\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param amounts The array of amounts to mint\n function _revealAsset(\n uint256 prevTokenId,\n string[] calldata metadataHashes,\n uint256[] calldata amounts,\n bytes32[] calldata revealHashes\n ) internal returns (uint256[] memory) {\n uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n require(revealHashesUsed[revealHashes[i]] == false, \"AssetReveal: RevealHash already used\");\n revealHashesUsed[revealHashes[i]] = true;\n }\n if (newTokenIds.length == 1) {\n assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]);\n } else {\n assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes);\n }\n return newTokenIds;\n }\n\n /// @notice Burns an asset to be able to reveal it later\n /// @param tokenId the tokenId of the asset to burn\n /// @param amount the amount of the asset to burn\n function _burnAsset(uint256 tokenId, uint256 amount) internal {\n _verifyBurnData(tokenId, amount);\n assetContract.burnFrom(_msgSender(), tokenId, amount);\n }\n\n function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal {\n require(tokenIds.length == amounts.length, \"AssetReveal: Invalid input\");\n for (uint256 i = 0; i < tokenIds.length; i++) {\n _verifyBurnData(tokenIds[i], amounts[i]);\n }\n assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts);\n }\n\n function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure {\n IAsset.AssetData memory data = tokenId.getData();\n require(!data.revealed, \"AssetReveal: Asset is already revealed\");\n require(amount > 0, \"AssetReveal: Burn amount should be greater than 0\");\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The address of the recipient\n /// @param prevTokenId The unrevealed token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashInstantReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n INSTANT_REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed token\n /// @param prevTokenId The previous token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed tokens\n /// @param prevTokenIds The previous token id\n /// @param amounts The amounts of tokens to mint\n /// @param metadataHashes The arrays of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashBatchReveal(\n address recipient,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n BATCH_REVEAL_TYPEHASH,\n recipient,\n keccak256(abi.encodePacked(prevTokenIds)),\n _encodeBatchAmounts(amounts),\n _encodeBatchHashes(metadataHashes),\n _encodeBatchRevealHashes(revealHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = _encodeHashes(metadataHashes[i]);\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param revealHashes The revealHashes\n /// @return encodedRevealHashes The encoded hashes of the metadata\n function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](revealHashes.length);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i]));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the amounts of the tokens for signature verification\n /// @param amounts The amounts of the tokens\n /// @return encodedAmounts The encoded amounts of the tokens\n function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) {\n bytes32[] memory encodedAmounts = new bytes32[](amounts.length);\n for (uint256 i = 0; i < amounts.length; i++) {\n encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i]));\n }\n return keccak256(abi.encodePacked(encodedAmounts));\n }\n\n /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't\n /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed\n /// @param metadataHashes The hashes of the metadata\n /// @param prevTokenId The previous token id from which the assets are revealed\n /// @return tokenIdArray The array of tokenIds to mint\n function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId)\n internal\n returns (uint256[] memory)\n {\n IAsset.AssetData memory data = prevTokenId.getData();\n require(!data.revealed, \"AssetReveal: already revealed\");\n uint256[] memory tokenIdArray = new uint256[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]);\n if (tokenId == 0) {\n uint16 revealNonce = ++revealIds[data.creator][prevTokenId];\n tokenId = TokenIdUtils.generateTokenId(\n data.creator,\n data.tier,\n data.creatorNonce,\n revealNonce,\n data.bridged\n );\n }\n tokenIdArray[i] = tokenId;\n }\n return tokenIdArray;\n }\n\n /// @notice Get the status of a revealHash\n /// @return Whether it has been used\n function revealHashUsed(bytes32 revealHash) external view returns (bool) {\n return revealHashesUsed[revealHash];\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: signer not set\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771HandlerUpgradeable,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_init(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771HandlerAbstract) returns (address) {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `interfaceId`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Catalyst: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Catalyst: registry can't be zero address\");\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetReveal {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetRevealBurn(address revealer, uint256 unrevealedTokenId, uint256 amount);\n event AssetRevealBatchBurn(address revealer, uint256[] unrevealedTokenIds, uint256[] amounts);\n event AssetRevealMint(\n address recipient,\n uint256 unrevealedTokenId,\n uint256[] amounts,\n uint256[] newTokenIds,\n bytes32[] revealHashes\n );\n event AssetRevealBatchMint(\n address recipient,\n uint256[] unrevealedTokenIds,\n uint256[][] amounts,\n uint256[][] newTokenIds,\n bytes32[][] revealHashes\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ITokenUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {IRoyaltyUGC} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol\";\n\ninterface ITokenUtils is IRoyaltyUGC {\n function getTier(uint256 tokenId) external pure returns (uint8 tier);\n\n function isRevealed(uint256 tokenId) external pure returns (bool);\n\n function getCreatorNonce(uint256 tokenId) external pure returns (uint16);\n\n function getRevealNonce(uint256 tokenId) external pure returns (uint16);\n\n function isBridged(uint256 tokenId) external pure returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0xFFFF;\n uint256 public constant REVEAL_NONCE_MASK = 0xFFFF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 184;\n uint256 public constant BRIDGED_SHIFT = 200;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetReveal} from \"../AssetReveal.sol\";\n\ncontract MockAssetReveal is AssetReveal {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyManager} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltySplitter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltySplitter} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\";\n\n/* solhint-disable-next-line no-empty-blocks*/\ncontract MockSplitter is RoyaltySplitter {\n\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\nabstract contract ERC2771HandlerAbstract {\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function isTrustedForwarder(address forwarder) external view returns (bool) {\n return _isTrustedForwarder(forwarder);\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual returns (address sender) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n sender = msg.sender;\n }\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual returns (bytes calldata) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n /// @dev this function must be IMPLEMENTED\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC2771HandlerAbstract} from \"./ERC2771HandlerAbstract.sol\";\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\n address private _trustedForwarder;\n\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\n /// @param oldTrustedForwarder old trusted forwarder\n /// @param newTrustedForwarder new trusted forwarder\n /// @param operator the sender of the transaction\n event TrustedForwarderSet(\n address indexed oldTrustedForwarder,\n address indexed newTrustedForwarder,\n address indexed operator\n );\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\n __ERC2771Handler_init_unchained(forwarder);\n }\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\n _setTrustedForwarder(forwarder);\n }\n\n /// @notice return the address of the trusted forwarder\n /// @return return the address of the trusted forwarder\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n /// @notice set the address of the trusted forwarder\n /// @param newForwarder the address of the new forwarder.\n function _setTrustedForwarder(address newForwarder) internal virtual {\n require(newForwarder != _trustedForwarder, \"ERC2771HandlerUpgradeable: forwarder already set\");\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\n _trustedForwarder = newForwarder;\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IERC20Approve {\n function approve(address spender, uint256 amount) external returns (bool);\n\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {IMultiRoyaltyRecipients} from \"./IMultiRoyaltyRecipients.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyDistributor is IERC165, IMultiRoyaltyRecipients {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, address recipient);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address recipient);\n\n event RoyaltyRecipientSet(address splitter, address recipient);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyRecipients.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyRecipients is IERC165 {\n /**\n * @dev Helper function to get all recipients\n */\n function getRecipients(uint256 tokenId) external view returns (Recipient[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address payable, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\n\n function setTrustedForwarder(address _newForwarder) external;\n\n function getTrustedForwarder() external view returns (address);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyUGC.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IRoyaltyUGC {\n function getCreatorAddress(uint256 tokenId) external pure returns (address creator);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\nimport {IMultiRoyaltyDistributor, IMultiRoyaltyRecipients} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributer\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributer contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to slip its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n address public royaltyManager;\n\n mapping(uint256 => address payable) public _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n function __MultiRoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = _royaltyManager;\n }\n\n /// @notice EIP 165 interface function\n /// @dev used to check the interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n interfaceId == type(IMultiRoyaltyRecipients).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n address payable recipient,\n address creator\n ) internal {\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n _tokenRoyaltiesSplitter[tokenId] = creatorSplitterAddress;\n _tokensWithRoyalties.push(tokenId);\n emit TokenRoyaltySet(tokenId, recipient);\n }\n\n /// @notice Returns royalty receivers and their split of royalty for each token\n /// @return royaltyConfigs receivers and their split array as long as the number of tokens.\n function getTokenRoyalties() external view override returns (TokenRoyaltyConfig[] memory royaltyConfigs) {\n royaltyConfigs = new TokenRoyaltyConfig[](_tokensWithRoyalties.length);\n for (uint256 i; i < _tokensWithRoyalties.length; ++i) {\n TokenRoyaltyConfig memory royaltyConfig;\n uint256 tokenId = _tokensWithRoyalties[i];\n address splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n royaltyConfig.recipients = IRoyaltySplitter(splitterAddress).getRecipients();\n }\n royaltyConfig.tokenId = tokenId;\n royaltyConfigs[i] = royaltyConfig;\n }\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return address the royalty receiver\n /// @return value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value) public view override returns (address, uint256) {\n (address payable _defaultRoyaltyReceiver, uint16 _defaultRoyaltyBPS) =\n IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return addresses of royalty recipient of the token.\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n (address payable _defaultRoyaltyReceiver, ) = IRoyaltyManager(royaltyManager).getRoyaltyInfo();\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n Recipient[] memory defaultRecipient = new Recipient[](1);\n defaultRecipient[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return defaultRecipient;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public _creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n address internal _trustedForwarder;\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n /// @param trustedForwarder the trustedForwarder address for royalty splitters to use.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter,\n address trustedForwarder\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n _trustedForwarder = trustedForwarder;\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[msg.sender];\n require(creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(creatorSplitterAddress)._recipient();\n require(_recipient != recipient, \"Manager: Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the trustedForwarder address to be used by the splitters\n /// @dev can only be called by the admin\n /// @param _newForwarder is the new trusted forwarder address\n /// @dev new splitters will be deployed with this setting; existing splitters will have to apply it\n function setTrustedForwarder(address _newForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _trustedForwarder = _newForwarder;\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n /// @notice get the current trustedForwarder address\n function getTrustedForwarder() public view returns (address) {\n return _trustedForwarder;\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set split greater than the total basis point\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n recipient = Recipient({recipient: commonRecipient, bps: commonSplit});\n return recipient;\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress deployed for a creator\n function deploySplitter(address creator, address payable recipient) external returns (address payable) {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n _creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable) {\n return _creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @return commonRecipient\n /// @return royaltySplit\n function getRoyaltyInfo() external view returns (address payable, uint16) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @param _contractAddress the address of the contract for which the royalty is required.\n /// @return royaltyBps royalty bps of the contarct\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps) {\n return contractRoyalty[_contractAddress];\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OwnableUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is\n Initializable,\n OwnableUpgradeable,\n IRoyaltySplitter,\n ERC165Upgradeable,\n ERC2771HandlerAbstract\n{\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n uint256 internal constant IERC20_APPROVE_SELECTOR =\n 0x095ea7b300000000000000000000000000000000000000000000000000000000;\n uint256 internal constant SELECTOR_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000;\n\n address payable public _recipient;\n IRoyaltyManager public _royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipient the wallet of the creator when the contract is deployed\n /// @param royaltyManager the address of the royalty manager contract\n function initialize(address payable recipient, address royaltyManager) public initializer {\n _royaltyManager = IRoyaltyManager(royaltyManager); // set manager before Ownable_init for _isTrustedForwarder\n _recipient = recipient;\n __Ownable_init();\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n _setRecipients(recipients);\n }\n\n function _setRecipients(Recipient[] calldata recipients) private {\n delete _recipient;\n require(recipients.length == 1, \"Invalid recipents length\");\n _recipient = recipients[0].recipient;\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients of royalty through this splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory recipients = new Recipient[](2);\n recipients[0].recipient = _recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() public payable {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n amountToSend = (value * recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) public {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == _msgSender() || _recipient == _msgSender(),\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n bool success;\n (success, amountToSend) = balance.tryMul(recipient.bps);\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n try erc20Contract.transfer(recipient.recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), recipient.recipient, amountToSend);\n } catch {\n return false;\n }\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n try erc20Contract.transfer(_recipients[0].recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n } catch {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice made for unexpected scenarios when assets are sent to this contact such that they could be recovered.\n /// @dev first attempts to split ERC20 tokens.\n /// @param target target of the call\n /// @param callData for the call.\n function proxyCall(address payable target, bytes calldata callData) external {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n require(\n commonRecipient.recipient == _msgSender() || _recipient == _msgSender(),\n \"Split: Can only be called by one of the recipients\"\n );\n require(\n !callData.startsWith(IERC20Approve.approve.selector) &&\n !callData.startsWith(IERC20Approve.increaseAllowance.selector),\n \"Split: ERC20 tokens must be split\"\n );\n /* solhint-disable-next-line no-empty-blocks*/\n try this.splitERC20Tokens(IERC20(target)) {} catch {}\n target.functionCall(callData);\n }\n\n /// @notice verify whether a forwarder address is the trustedForwarder address, using the manager setting\n /// @dev this function is used to avoid having a trustedForwarder variable inside the splitter\n /// @return bool whether the forwarder is the trusted address\n function _isTrustedForwarder(address forwarder) internal view override(ERC2771HandlerAbstract) returns (bool) {\n return forwarder == _royaltyManager.getTrustedForwarder();\n }\n\n function _msgSender()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (address sender)\n {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/eebf437e3a918f2514b50d71228bf8a9.json b/packages/deploy/deployments/mumbai/solcInputs/eebf437e3a918f2514b50d71228bf8a9.json new file mode 100644 index 0000000000..908c4915d0 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/eebf437e3a918f2514b50d71228bf8a9.json @@ -0,0 +1,407 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/libraries-solidity/contracts/access/IAdminControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface for admin control\n */\ninterface IAdminControl is IERC165 {\n\n event AdminApproved(address indexed account, address indexed sender);\n event AdminRevoked(address indexed account, address indexed sender);\n\n /**\n * @dev gets address of all admins\n */\n function getAdmins() external view returns (address[] memory);\n\n /**\n * @dev add an admin. Can only be called by contract owner.\n */\n function approveAdmin(address admin) external;\n\n /**\n * @dev remove an admin. Can only be called by contract owner.\n */\n function revokeAdmin(address admin) external;\n\n /**\n * @dev checks whether or not given address is an admin\n * Returns True if they are\n */\n function isAdmin(address admin) external view returns (bool);\n\n}" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/FallbackRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport { Recipient } from \"./overrides/IRoyaltySplitter.sol\";\nimport { Ownable2Step } from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\nimport { IFallbackRegistry } from \"./overrides/IFallbackRegistry.sol\";\n\ncontract FallbackRegistry is IFallbackRegistry, Ownable2Step {\n struct TokenFallback {\n address tokenAddress;\n Recipient[] recipients;\n }\n\n mapping(address => Recipient[]) fallbacks;\n\n constructor(address initialOwner) {\n _transferOwnership(initialOwner);\n }\n\n function setFallback(address tokenAddress, Recipient[] calldata _recipients) public onlyOwner {\n Recipient[] storage recipients = fallbacks[tokenAddress];\n uint256 recipientsLength = _recipients.length;\n ///@solidity memory-safe-assembly\n assembly {\n // overwrite length directly rather than deleting and then updating it each time we push new values\n // this means if the new array is shorter than the old ones, those slots will stay dirty, but they\n // should not be able to be accessed due to the new length\n sstore(recipients.slot, recipientsLength)\n }\n for (uint256 i; i < recipientsLength;) {\n recipients[i] = _recipients[i];\n unchecked {\n ++i;\n }\n }\n }\n\n function setFallbacks(TokenFallback[] calldata bundle) external onlyOwner {\n uint256 bundleLength = bundle.length;\n for (uint256 i = 0; i < bundleLength;) {\n TokenFallback calldata tokenFallback = bundle[i];\n setFallback(tokenFallback.tokenAddress, tokenFallback.recipients);\n unchecked {\n ++i;\n }\n }\n }\n\n function getRecipients(address tokenAddress) external view returns (Recipient[] memory) {\n return fallbacks[tokenAddress];\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyEngineV1.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Lookup engine interface\n */\ninterface IRoyaltyEngineV1 is IERC165 {\n /**\n * Get the royalty for a given token (address, id) and value amount. Does not cache the bps/amounts. Caches the spec for a given token address\n *\n * @param tokenAddress - The address of the token\n * @param tokenId - The id of the token\n * @param value - The value you wish to get the royalty of\n *\n * returns Two arrays of equal length, royalty recipients and the corresponding amount each recipient should get\n */\n function getRoyalty(address tokenAddress, uint256 tokenId, uint256 value)\n external\n returns (address payable[] memory recipients, uint256[] memory amounts);\n\n /**\n * View only version of getRoyalty\n *\n * @param tokenAddress - The address of the token\n * @param tokenId - The id of the token\n * @param value - The value you wish to get the royalty of\n *\n * returns Two arrays of equal length, royalty recipients and the corresponding amount each recipient should get\n */\n function getRoyaltyView(address tokenAddress, uint256 tokenId, uint256 value)\n external\n view\n returns (address payable[] memory recipients, uint256[] memory amounts);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Royalty registry interface\n */\ninterface IRoyaltyRegistry is IERC165 {\n event RoyaltyOverride(address owner, address tokenAddress, address royaltyAddress);\n\n /**\n * Override the location of where to look up royalty information for a given token contract.\n * Allows for backwards compatibility and implementation of royalty logic for contracts that did not previously support them.\n *\n * @param tokenAddress - The token address you wish to override\n * @param royaltyAddress - The royalty override address\n */\n function setRoyaltyLookupAddress(address tokenAddress, address royaltyAddress) external returns (bool);\n\n /**\n * Returns royalty address location. Returns the tokenAddress by default, or the override if it exists\n *\n * @param tokenAddress - The token address you are looking up the royalty for\n */\n function getRoyaltyLookupAddress(address tokenAddress) external view returns (address);\n\n /**\n * Returns the token address that an overrideAddress is set for.\n * Note: will not be accurate if the override was created before this function was added.\n *\n * @param overrideAddress - The override address you are looking up the token for\n */\n function getOverrideLookupTokenAddress(address overrideAddress) external view returns (address);\n\n /**\n * Whether or not the message sender can override the royalty address for the given token address\n *\n * @param tokenAddress - The token address you are looking up the royalty for\n */\n function overrideAllowed(address tokenAddress) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\n/**\n * @notice A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n /**\n * @dev Replace the address at the given location in a byte array if the contents at that location\n * match the expected address.\n */\n function replaceAtIf(bytes memory data, uint256 startLocation, address expectedAddress, address newAddress)\n internal\n pure\n {\n bytes memory expectedData = abi.encodePacked(expectedAddress);\n bytes memory newData = abi.encodePacked(newAddress);\n // An address is 20 bytes long\n for (uint256 i = 0; i < 20; i++) {\n uint256 dataLocation = startLocation + i;\n require(data[dataLocation] == expectedData[i], \"Bytes: Data provided does not include the expectedAddress\");\n data[dataLocation] = newData[i];\n }\n }\n\n /**\n * @dev Checks if the call data starts with the given function signature.\n */\n function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n // A signature is 4 bytes long\n if (callData.length < 4) {\n return false;\n }\n for (uint256 i = 0; i < 4; i++) {\n if (callData[i] != functionSig[i]) {\n return false;\n }\n }\n\n return true;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/libraries/SuperRareContracts.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nlibrary SuperRareContracts {\n address public constant SUPERRARE_REGISTRY = 0x17B0C8564E53f22364A6C8de6F7ca5CE9BEa4e5D;\n address public constant SUPERRARE_V1 = 0x41A322b28D0fF354040e2CbC676F0320d8c8850d;\n address public constant SUPERRARE_V2 = 0xb932a70A57673d89f4acfFBE830E8ed7f75Fb9e0;\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IFallbackRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport { Recipient } from \"./IRoyaltySplitter.sol\";\n\ninterface IFallbackRegistry {\n /**\n * @dev Get total recipients for token fees. Note that recipient bps is of gross amount, not share of fee amount,\n * ie, recipients' BPS will not sum to 10_000, but to the total fee BPS for an order.\n */\n function getRecipients(address tokenAddress) external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IEIP2981MultiReceiverRoyaltyOverride is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, Recipient[] recipients);\n event DefaultRoyaltySet(uint16 royaltyBPS, Recipient[] recipients);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(TokenRoyaltyConfig[] calldata royalties) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty configuration. Will be used if no token specific configuration is set\n */\n function setDefaultRoyalty(uint16 bps, Recipient[] calldata recipients) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyEngineV1.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport { ERC165, IERC165 } from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport { ERC165Checker } from \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { AddressUpgradeable } from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport { SuperRareContracts } from \"./libraries/SuperRareContracts.sol\";\n\nimport { IManifold } from \"./specs/IManifold.sol\";\nimport { IRaribleV1, IRaribleV2 } from \"./specs/IRarible.sol\";\nimport { IFoundation } from \"./specs/IFoundation.sol\";\nimport { ISuperRareRegistry } from \"./specs/ISuperRare.sol\";\nimport { IEIP2981 } from \"./specs/IEIP2981.sol\";\nimport { IZoraOverride } from \"./specs/IZoraOverride.sol\";\nimport { IArtBlocksOverride } from \"./specs/IArtBlocksOverride.sol\";\nimport { IKODAV2Override } from \"./specs/IKODAV2Override.sol\";\nimport { IRoyaltyEngineV1 } from \"./IRoyaltyEngineV1.sol\";\nimport { IRoyaltyRegistry } from \"./IRoyaltyRegistry.sol\";\nimport { IRoyaltySplitter, Recipient } from \"./overrides/IRoyaltySplitter.sol\";\nimport { IFallbackRegistry } from \"./overrides/IFallbackRegistry.sol\";\n/**\n * @dev Engine to lookup royalty configurations\n */\n\ncontract RoyaltyEngineV1 is ERC165, OwnableUpgradeable, IRoyaltyEngineV1 {\n using AddressUpgradeable for address;\n\n // Use int16 for specs to support future spec additions\n // When we add a spec, we also decrement the NONE value\n // Anything > NONE and <= NOT_CONFIGURED is considered not configured\n int16 private constant NONE = -1;\n int16 private constant NOT_CONFIGURED = 0;\n int16 private constant MANIFOLD = 1;\n int16 private constant RARIBLEV1 = 2;\n int16 private constant RARIBLEV2 = 3;\n int16 private constant FOUNDATION = 4;\n int16 private constant EIP2981 = 5;\n int16 private constant SUPERRARE = 6;\n int16 private constant ZORA = 7;\n int16 private constant ARTBLOCKS = 8;\n int16 private constant KNOWNORIGINV2 = 9;\n int16 private constant ROYALTY_SPLITTER = 10;\n int16 private constant FALLBACK = type(int16).max;\n\n mapping(address => int16) _specCache;\n\n address public royaltyRegistry;\n IFallbackRegistry public immutable FALLBACK_REGISTRY;\n\n constructor(address fallbackRegistry) {\n FALLBACK_REGISTRY = IFallbackRegistry(fallbackRegistry);\n }\n\n function initialize(address _initialOwner, address royaltyRegistry_) public initializer {\n _transferOwnership(_initialOwner);\n require(ERC165Checker.supportsInterface(royaltyRegistry_, type(IRoyaltyRegistry).interfaceId));\n royaltyRegistry = royaltyRegistry_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override (ERC165, IERC165) returns (bool) {\n return interfaceId == type(IRoyaltyEngineV1).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Invalidate the cached spec (useful for situations where tooken royalty implementation changes to a different spec)\n */\n function invalidateCachedRoyaltySpec(address tokenAddress) public {\n address royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n delete _specCache[royaltyAddress];\n }\n\n /**\n * @dev View function to get the cached spec of a token\n */\n function getCachedRoyaltySpec(address tokenAddress) public view returns (int16) {\n address royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n return _specCache[royaltyAddress];\n }\n\n /**\n * @dev See {IRoyaltyEngineV1-getRoyalty}\n */\n function getRoyalty(address tokenAddress, uint256 tokenId, uint256 value)\n public\n override\n returns (address payable[] memory recipients, uint256[] memory amounts)\n {\n // External call to limit gas\n try this._getRoyaltyAndSpec{gas: 100000}(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients,\n uint256[] memory _amounts,\n int16 spec,\n address royaltyAddress,\n bool addToCache\n ) {\n if (addToCache) _specCache[royaltyAddress] = spec;\n return (_recipients, _amounts);\n } catch {\n revert(\"Invalid royalty amount\");\n }\n }\n\n /**\n * @dev See {IRoyaltyEngineV1-getRoyaltyView}.\n */\n function getRoyaltyView(address tokenAddress, uint256 tokenId, uint256 value)\n public\n view\n override\n returns (address payable[] memory recipients, uint256[] memory amounts)\n {\n // External call to limit gas\n try this._getRoyaltyAndSpec{gas: 100000}(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients, uint256[] memory _amounts, int16, address, bool\n ) {\n return (_recipients, _amounts);\n } catch {\n revert(\"Invalid royalty amount\");\n }\n }\n\n /**\n * @dev Get the royalty and royalty spec for a given token\n *\n * returns recipients array, amounts array, royalty spec, royalty address, whether or not to add to cache\n */\n function _getRoyaltyAndSpec(address tokenAddress, uint256 tokenId, uint256 value)\n external\n view\n returns (\n address payable[] memory recipients,\n uint256[] memory amounts,\n int16 spec,\n address royaltyAddress,\n bool addToCache\n )\n {\n require(msg.sender == address(this), \"Only Engine\");\n\n royaltyAddress = IRoyaltyRegistry(royaltyRegistry).getRoyaltyLookupAddress(tokenAddress);\n spec = _specCache[royaltyAddress];\n\n if (spec <= NOT_CONFIGURED && spec > NONE) {\n // No spec configured yet, so we need to detect the spec\n addToCache = true;\n\n // SuperRare handling\n if (tokenAddress == SuperRareContracts.SUPERRARE_V1 || tokenAddress == SuperRareContracts.SUPERRARE_V2) {\n try ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).tokenCreator(tokenAddress, tokenId)\n returns (address payable creator) {\n try ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).calculateRoyaltyFee(\n tokenAddress, tokenId, value\n ) returns (uint256 amount) {\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = creator;\n amounts[0] = amount;\n return (recipients, amounts, SUPERRARE, royaltyAddress, addToCache);\n } catch { }\n } catch { }\n }\n try IEIP2981(royaltyAddress).royaltyInfo(tokenId, value) returns (address recipient, uint256 amount) {\n require(amount < value, \"Invalid royalty amount\");\n uint32 recipientSize;\n assembly {\n recipientSize := extcodesize(recipient)\n }\n if (recipientSize > 0) {\n try IRoyaltySplitter(recipient).getRecipients() returns (Recipient[] memory splitRecipients) {\n recipients = new address payable[](splitRecipients.length);\n amounts = new uint256[](splitRecipients.length);\n uint256 sum = 0;\n uint256 splitRecipientsLength = splitRecipients.length;\n for (uint256 i = 0; i < splitRecipientsLength;) {\n Recipient memory splitRecipient = splitRecipients[i];\n recipients[i] = payable(splitRecipient.recipient);\n uint256 splitAmount = splitRecipient.bps * amount / 10000;\n amounts[i] = splitAmount;\n sum += splitAmount;\n unchecked {\n ++i;\n }\n }\n // sum can be less than amount, otherwise small-value listings can break\n require(sum <= amount, \"Invalid split\");\n\n return (recipients, amounts, ROYALTY_SPLITTER, royaltyAddress, addToCache);\n } catch { }\n }\n // Supports EIP2981. Return amounts\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = payable(recipient);\n amounts[0] = amount;\n return (recipients, amounts, EIP2981, royaltyAddress, addToCache);\n } catch { }\n try IManifold(royaltyAddress).getRoyalties(tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Supports manifold interface. Compute amounts\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), MANIFOLD, royaltyAddress, addToCache);\n } catch { }\n try IRaribleV2(royaltyAddress).getRaribleV2Royalties(tokenId) returns (IRaribleV2.Part[] memory royalties) {\n // Supports rarible v2 interface. Compute amounts\n recipients = new address payable[](royalties.length);\n amounts = new uint256[](royalties.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < royalties.length; i++) {\n recipients[i] = royalties[i].account;\n amounts[i] = value * royalties[i].value / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, RARIBLEV2, royaltyAddress, addToCache);\n } catch { }\n try IRaribleV1(royaltyAddress).getFeeRecipients(tokenId) returns (address payable[] memory recipients_) {\n // Supports rarible v1 interface. Compute amounts\n recipients_ = IRaribleV1(royaltyAddress).getFeeRecipients(tokenId);\n try IRaribleV1(royaltyAddress).getFeeBps(tokenId) returns (uint256[] memory bps) {\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), RARIBLEV1, royaltyAddress, addToCache);\n } catch { }\n } catch { }\n try IFoundation(royaltyAddress).getFees(tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Supports foundation interface. Compute amounts\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), FOUNDATION, royaltyAddress, addToCache);\n } catch { }\n try IZoraOverride(royaltyAddress).convertBidShares(tokenAddress, tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Support Zora override\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), ZORA, royaltyAddress, addToCache);\n } catch { }\n try IArtBlocksOverride(royaltyAddress).getRoyalties(tokenAddress, tokenId) returns (\n address payable[] memory recipients_, uint256[] memory bps\n ) {\n // Support Art Blocks override\n require(recipients_.length == bps.length);\n return (recipients_, _computeAmounts(value, bps), ARTBLOCKS, royaltyAddress, addToCache);\n } catch { }\n try IKODAV2Override(royaltyAddress).getKODAV2RoyaltyInfo(tokenAddress, tokenId, value) returns (\n address payable[] memory _recipients, uint256[] memory _amounts\n ) {\n // Support KODA V2 override\n require(_recipients.length == _amounts.length);\n return (_recipients, _amounts, KNOWNORIGINV2, royaltyAddress, addToCache);\n } catch { }\n\n try FALLBACK_REGISTRY.getRecipients(tokenAddress) returns (Recipient[] memory _recipients) {\n uint256 recipientsLength = _recipients.length;\n if (recipientsLength > 0) {\n return _calculateFallback(_recipients, recipientsLength, value, royaltyAddress, addToCache);\n }\n } catch { }\n\n // No supported royalties configured\n return (recipients, amounts, NONE, royaltyAddress, addToCache);\n } else {\n // Spec exists, just execute the appropriate one\n addToCache = false;\n if (spec == NONE) {\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == FALLBACK) {\n Recipient[] memory _recipients = FALLBACK_REGISTRY.getRecipients(tokenAddress);\n return _calculateFallback(_recipients, _recipients.length, value, royaltyAddress, addToCache);\n } else if (spec == MANIFOLD) {\n // Manifold spec\n uint256[] memory bps;\n (recipients, bps) = IManifold(royaltyAddress).getRoyalties(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == RARIBLEV2) {\n // Rarible v2 spec\n IRaribleV2.Part[] memory royalties;\n royalties = IRaribleV2(royaltyAddress).getRaribleV2Royalties(tokenId);\n recipients = new address payable[](royalties.length);\n amounts = new uint256[](royalties.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < royalties.length; i++) {\n recipients[i] = royalties[i].account;\n amounts[i] = value * royalties[i].value / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == RARIBLEV1) {\n // Rarible v1 spec\n uint256[] memory bps;\n recipients = IRaribleV1(royaltyAddress).getFeeRecipients(tokenId);\n bps = IRaribleV1(royaltyAddress).getFeeBps(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == FOUNDATION) {\n // Foundation spec\n uint256[] memory bps;\n (recipients, bps) = IFoundation(royaltyAddress).getFees(tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == EIP2981 || spec == ROYALTY_SPLITTER) {\n // EIP2981 spec\n (address recipient, uint256 amount) = IEIP2981(royaltyAddress).royaltyInfo(tokenId, value);\n require(amount < value, \"Invalid royalty amount\");\n if (spec == ROYALTY_SPLITTER) {\n Recipient[] memory splitRecipients = IRoyaltySplitter(recipient).getRecipients();\n recipients = new address payable[](splitRecipients.length);\n amounts = new uint256[](splitRecipients.length);\n uint256 sum = 0;\n uint256 splitRecipientsLength = splitRecipients.length;\n for (uint256 i = 0; i < splitRecipientsLength;) {\n Recipient memory splitRecipient = splitRecipients[i];\n recipients[i] = payable(splitRecipient.recipient);\n uint256 splitAmount = splitRecipient.bps * amount / 10000;\n amounts[i] = splitAmount;\n sum += splitAmount;\n unchecked {\n ++i;\n }\n }\n // sum can be less than amount, otherwise small-value listings can break\n require(sum <= value, \"Invalid split\");\n\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n }\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = payable(recipient);\n amounts[0] = amount;\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == SUPERRARE) {\n // SUPERRARE spec\n address payable creator =\n ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).tokenCreator(tokenAddress, tokenId);\n uint256 amount = ISuperRareRegistry(SuperRareContracts.SUPERRARE_REGISTRY).calculateRoyaltyFee(\n tokenAddress, tokenId, value\n );\n recipients = new address payable[](1);\n amounts = new uint256[](1);\n recipients[0] = creator;\n amounts[0] = amount;\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n } else if (spec == ZORA) {\n // Zora spec\n uint256[] memory bps;\n (recipients, bps) = IZoraOverride(royaltyAddress).convertBidShares(tokenAddress, tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == ARTBLOCKS) {\n // Art Blocks spec\n uint256[] memory bps;\n (recipients, bps) = IArtBlocksOverride(royaltyAddress).getRoyalties(tokenAddress, tokenId);\n require(recipients.length == bps.length);\n return (recipients, _computeAmounts(value, bps), spec, royaltyAddress, addToCache);\n } else if (spec == KNOWNORIGINV2) {\n // KnownOrigin.io V2 spec (V3 falls under EIP2981)\n (recipients, amounts) =\n IKODAV2Override(royaltyAddress).getKODAV2RoyaltyInfo(tokenAddress, tokenId, value);\n require(recipients.length == amounts.length);\n return (recipients, amounts, spec, royaltyAddress, addToCache);\n }\n }\n }\n\n function _calculateFallback(\n Recipient[] memory _recipients,\n uint256 recipientsLength,\n uint256 value,\n address royaltyAddress,\n bool addToCache\n )\n internal\n pure\n returns (\n address payable[] memory recipients,\n uint256[] memory amounts,\n int16 spec,\n address _royaltyAddress,\n bool _addToCache\n )\n {\n recipients = new address payable[](recipientsLength);\n amounts = new uint256[](recipientsLength);\n uint256 totalAmount;\n for (uint256 i = 0; i < recipientsLength;) {\n Recipient memory recipient = _recipients[i];\n recipients[i] = payable(recipient.recipient);\n uint256 amount = value * recipient.bps / 10_000;\n amounts[i] = amount;\n totalAmount += amount;\n unchecked {\n ++i;\n }\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return (recipients, amounts, FALLBACK, royaltyAddress, addToCache);\n }\n\n /**\n * Compute royalty amounts\n */\n function _computeAmounts(uint256 value, uint256[] memory bps) private pure returns (uint256[] memory amounts) {\n amounts = new uint256[](bps.length);\n uint256 totalAmount;\n for (uint256 i = 0; i < bps.length; i++) {\n amounts[i] = value * bps[i] / 10000;\n totalAmount += amounts[i];\n }\n require(totalAmount < value, \"Invalid royalty amount\");\n return amounts;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\"; \nimport \"@openzeppelin/contracts/utils/introspection/ERC165Checker.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@manifoldxyz/libraries-solidity/contracts/access/IAdminControl.sol\";\n\nimport \"./IRoyaltyRegistry.sol\";\nimport \"./specs/INiftyGateway.sol\";\nimport \"./specs/IFoundation.sol\";\nimport \"./specs/IDigitalax.sol\";\nimport \"./specs/IArtBlocks.sol\";\n\n/**\n * @dev Registry to lookup royalty configurations\n */\ncontract RoyaltyRegistry is ERC165, OwnableUpgradeable, IRoyaltyRegistry {\n using AddressUpgradeable for address;\n\n address public immutable OVERRIDE_FACTORY;\n\n /**\n * @notice Constructor arg allows efficient lookup of override factory for single-tx overrides.\n * However, this means the RoyaltyRegistry will need to be upgraded if the override factory is changed.\n */\n constructor(address overrideFactory) {\n OVERRIDE_FACTORY = overrideFactory;\n }\n\n // Override addresses\n mapping(address => address) private _overrides;\n mapping(address => address) private _overrideLookupToTokenContract;\n\n function initialize(address _initialOwner) public initializer {\n _transferOwnership(_initialOwner);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override (ERC165, IERC165) returns (bool) {\n return interfaceId == type(IRoyaltyRegistry).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IRegistry-getRoyaltyLookupAddress}.\n */\n function getRoyaltyLookupAddress(address tokenAddress) external view override returns (address) {\n address override_ = _overrides[tokenAddress];\n if (override_ != address(0)) {\n return override_;\n }\n return tokenAddress;\n }\n\n /**\n * @dev See {IRegistry-getOverrideTokenAddress}.\n */\n function getOverrideLookupTokenAddress(address overrideAddress) external view override returns (address) {\n return _overrideLookupToTokenContract[overrideAddress];\n }\n\n /**\n * @dev See {IRegistry-setRoyaltyLookupAddress}.\n */\n function setRoyaltyLookupAddress(address tokenAddress, address royaltyLookupAddress)\n public\n override\n returns (bool)\n {\n require(\n tokenAddress.isContract() && (royaltyLookupAddress.isContract() || royaltyLookupAddress == address(0)),\n \"Invalid input\"\n );\n require(overrideAllowed(tokenAddress), \"Permission denied\");\n // look up existing override, if any\n address existingOverride = _overrides[tokenAddress];\n if (existingOverride != address(0)) {\n // delete existing override reverse-lookup\n _overrideLookupToTokenContract[existingOverride] = address(0);\n }\n _overrideLookupToTokenContract[royaltyLookupAddress] = tokenAddress;\n // set new override and reverse-lookup\n _overrides[tokenAddress] = royaltyLookupAddress;\n\n emit RoyaltyOverride(_msgSender(), tokenAddress, royaltyLookupAddress);\n return true;\n }\n\n /**\n * @dev See {IRegistry-overrideAllowed}.\n */\n function overrideAllowed(address tokenAddress) public view override returns (bool) {\n if (owner() == _msgSender()) return true;\n\n if (\n ERC165Checker.supportsInterface(tokenAddress, type(IAdminControl).interfaceId)\n && IAdminControl(tokenAddress).isAdmin(_msgSender())\n ) {\n return true;\n }\n\n try OwnableUpgradeable(tokenAddress).owner() returns (address owner) {\n if (owner == _msgSender()) return true;\n\n if (owner.isContract()) {\n try OwnableUpgradeable(owner).owner() returns (address passThroughOwner) {\n if (passThroughOwner == _msgSender()) return true;\n } catch { }\n }\n } catch { }\n\n try IAccessControlUpgradeable(tokenAddress).hasRole(0x00, _msgSender()) returns (bool hasRole) {\n if (hasRole) return true;\n } catch { }\n\n // Nifty Gateway overrides\n try INiftyBuilderInstance(tokenAddress).niftyRegistryContract() returns (address niftyRegistry) {\n try INiftyRegistry(niftyRegistry).isValidNiftySender(_msgSender()) returns (bool valid) {\n return valid;\n } catch { }\n } catch { }\n\n // OpenSea overrides\n // Tokens already support Ownable\n\n // Foundation overrides\n try IFoundationTreasuryNode(tokenAddress).getFoundationTreasury() returns (address payable foundationTreasury) {\n try IFoundationTreasury(foundationTreasury).isAdmin(_msgSender()) returns (bool isAdmin) {\n return isAdmin;\n } catch { }\n } catch { }\n\n // DIGITALAX overrides\n try IDigitalax(tokenAddress).accessControls() returns (address externalAccessControls) {\n try IDigitalaxAccessControls(externalAccessControls).hasAdminRole(_msgSender()) returns (bool hasRole) {\n if (hasRole) return true;\n } catch { }\n } catch { }\n\n // Art Blocks overrides\n try IArtBlocks(tokenAddress).admin() returns (address admin) {\n if (admin == _msgSender()) return true;\n } catch { }\n\n // Superrare overrides\n // Tokens and registry already support Ownable\n\n // Rarible overrides\n // Tokens already support Ownable\n\n return false;\n }\n\n function _msgSender() internal view virtual override (ContextUpgradeable) returns (address) {\n if (msg.sender == OVERRIDE_FACTORY) {\n address relayedSender;\n ///@solidity memory-safe-assembly\n assembly {\n // the factory appends the original msg.sender as last the word of calldata, which we can read using\n // calldataload\n relayedSender := calldataload(sub(calldatasize(), 0x20))\n }\n return relayedSender;\n }\n // otherwise return msg.sender as normal\n return msg.sender;\n }\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IArtBlocks.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Art Blocks nfts\n */\ninterface IArtBlocks {\n // document getter function of public variable\n function admin() external view returns (address);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IArtBlocksOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * Interface for an Art Blocks override\n */\ninterface IArtBlocksOverride {\n /**\n * @dev Get royalites of a token at a given tokenAddress.\n * Returns array of receivers and basisPoints.\n *\n * bytes4(keccak256('getRoyalties(address,uint256)')) == 0x9ca7dc7a\n *\n * => 0x9ca7dc7a = 0x9ca7dc7a\n */\n function getRoyalties(address tokenAddress, uint256 tokenId)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IDigitalax.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Digitalax nfts\n */\ninterface IDigitalax {\n function accessControls() external view returns (address);\n}\n\n/**\n * @dev Digitalax Access Controls Simple\n */\ninterface IDigitalaxAccessControls {\n function hasAdminRole(address _account) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * EIP-2981\n */\ninterface IEIP2981 {\n /**\n * bytes4(keccak256(\"royaltyInfo(uint256,uint256)\")) == 0x2a55205a\n *\n * => 0x2a55205a = 0x2a55205a\n */\n function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IFoundation.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IFoundation {\n /*\n * bytes4(keccak256('getFees(uint256)')) == 0xd5a06d4c\n *\n * => 0xd5a06d4c = 0xd5a06d4c\n */\n function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);\n}\n\ninterface IFoundationTreasuryNode {\n function getFoundationTreasury() external view returns (address payable);\n}\n\ninterface IFoundationTreasury {\n function isAdmin(address account) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IKODAV2Override.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n/// @author: knownorigin.io\n\npragma solidity ^0.8.0;\n\ninterface IKODAV2 {\n function editionOfTokenId(uint256 _tokenId) external view returns (uint256 _editionNumber);\n\n function artistCommission(uint256 _editionNumber)\n external\n view\n returns (address _artistAccount, uint256 _artistCommission);\n\n function editionOptionalCommission(uint256 _editionNumber)\n external\n view\n returns (uint256 _rate, address _recipient);\n}\n\ninterface IKODAV2Override {\n /// @notice Emitted when the royalties fee changes\n event CreatorRoyaltiesFeeUpdated(uint256 _oldCreatorRoyaltiesFee, uint256 _newCreatorRoyaltiesFee);\n\n /// @notice For the given KO NFT and token ID, return the addresses and the amounts to pay\n function getKODAV2RoyaltyInfo(address _tokenAddress, uint256 _id, uint256 _amount)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n\n /// @notice Allows the owner() to update the creator royalties\n function updateCreatorRoyalties(uint256 _creatorRoyaltiesFee) external;\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IManifold.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\n/**\n * @dev Royalty interface for creator core classes\n */\ninterface IManifold {\n /**\n * @dev Get royalites of a token. Returns list of receivers and basisPoints\n *\n * bytes4(keccak256('getRoyalties(uint256)')) == 0xbb3bafd6\n *\n * => 0xbb3bafd6 = 0xbb3bafd6\n */\n function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/INiftyGateway.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Nifty builder instance\n */\ninterface INiftyBuilderInstance {\n function niftyRegistryContract() external view returns (address);\n}\n\n/**\n * @dev Nifty registry\n */\ninterface INiftyRegistry {\n /**\n * @dev function to see if sending key is valid\n */\n function isValidNiftySender(address sending_key) external view returns (bool);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IRarible.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IRaribleV1 {\n /*\n * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f\n * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb\n *\n * => 0x0ebd4c7f ^ 0xb9c4d9fb == 0xb7799584\n */\n function getFeeBps(uint256 id) external view returns (uint256[] memory);\n function getFeeRecipients(uint256 id) external view returns (address payable[] memory);\n}\n\ninterface IRaribleV2 {\n /*\n * bytes4(keccak256('getRaribleV2Royalties(uint256)')) == 0xcad96cca\n */\n struct Part {\n address payable account;\n uint96 value;\n }\n\n function getRaribleV2Royalties(uint256 id) external view returns (Part[] memory);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/ISuperRare.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface ISuperRareRegistry {\n /**\n * @dev Get the royalty fee percentage for a specific ERC721 contract.\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n * @return uint8 wei royalty fee.\n */\n function getERC721TokenRoyaltyPercentage(address _contractAddress, uint256 _tokenId)\n external\n view\n returns (uint8);\n\n /**\n * @dev Utililty function to calculate the royalty fee for a token.\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n * @param _amount uint256 wei amount.\n * @return uint256 wei fee.\n */\n function calculateRoyaltyFee(address _contractAddress, uint256 _tokenId, uint256 _amount)\n external\n view\n returns (uint256);\n\n /**\n * @dev Get the token creator which will receive royalties of the given token\n * @param _contractAddress address ERC721Contract address.\n * @param _tokenId uint256 token ID.\n */\n function tokenCreator(address _contractAddress, uint256 _tokenId) external view returns (address payable);\n}\n" + }, + "@manifoldxyz/royalty-registry-solidity/contracts/specs/IZoraOverride.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * Paired down version of the Zora Market interface\n */\ninterface IZoraMarket {\n struct ZoraDecimal {\n uint256 value;\n }\n\n struct ZoraBidShares {\n // % of sale value that goes to the _previous_ owner of the nft\n ZoraDecimal prevOwner;\n // % of sale value that goes to the original creator of the nft\n ZoraDecimal creator;\n // % of sale value that goes to the seller (current owner) of the nft\n ZoraDecimal owner;\n }\n\n function bidSharesForToken(uint256 tokenId) external view returns (ZoraBidShares memory);\n}\n\n/**\n * Paired down version of the Zora Media interface\n */\ninterface IZoraMedia {\n /**\n * Auto-generated accessors of public variables\n */\n function marketContract() external view returns (address);\n function previousTokenOwners(uint256 tokenId) external view returns (address);\n function tokenCreators(uint256 tokenId) external view returns (address);\n\n /**\n * ERC721 function\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n}\n\n/**\n * Interface for a Zora media override\n */\ninterface IZoraOverride {\n /**\n * @dev Convert bid share configuration of a Zora Media token into an array of receivers and bps values\n * Does not support prevOwner and sell-on amounts as that is specific to Zora marketplace implementation\n * and requires updates on the Zora Media and Marketplace to update the sell-on amounts/previous owner values.\n * An off-Zora marketplace sale will break the sell-on functionality.\n */\n function convertBidShares(address media, uint256 tokenId)\n external\n view\n returns (address payable[] memory, uint256[] memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.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/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * 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 OwnableUpgradeable is Initializable, ContextUpgradeable {\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 function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC1155/IERC1155Upgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC5267Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\n\npragma solidity ^0.8.0;\n\ninterface IERC5267Upgradeable {\n /**\n * @dev MAY be emitted to signal that the domain could have changed.\n */\n event EIP712DomainChanged();\n\n /**\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\n * signature.\n */\n function eip712Domain()\n external\n view\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n );\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.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 \"../StringsUpgradeable.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 ECDSAUpgradeable {\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\", StringsUpgradeable.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-upgradeable/utils/cryptography/EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\n\npragma solidity ^0.8.8;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../interfaces/IERC5267Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable {\n bytes32 private constant _TYPE_HASH =\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /// @custom:oz-renamed-from _HASHED_NAME\n bytes32 private _hashedName;\n /// @custom:oz-renamed-from _HASHED_VERSION\n bytes32 private _hashedVersion;\n\n string private _name;\n string private _version;\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n _name = name;\n _version = version;\n\n // Reset prior values in storage if upgrading\n _hashedName = 0;\n _hashedVersion = 0;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator();\n }\n\n function _buildDomainSeparator() private view returns (bytes32) {\n return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev See {EIP-5267}.\n *\n * _Available since v4.9._\n */\n function eip712Domain()\n public\n view\n virtual\n override\n returns (\n bytes1 fields,\n string memory name,\n string memory version,\n uint256 chainId,\n address verifyingContract,\n bytes32 salt,\n uint256[] memory extensions\n )\n {\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\n // and the EIP712 domain is not reliable, as it will be missing name and version.\n require(_hashedName == 0 && _hashedVersion == 0, \"EIP712: Uninitialized\");\n\n return (\n hex\"0f\", // 01111\n _EIP712Name(),\n _EIP712Version(),\n block.chainid,\n address(this),\n bytes32(0),\n new uint256[](0)\n );\n }\n\n /**\n * @dev The name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Name() internal virtual view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev The version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712Version() internal virtual view returns (string memory) {\n return _version;\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\n */\n function _EIP712NameHash() internal view returns (bytes32) {\n string memory name = _EIP712Name();\n if (bytes(name).length > 0) {\n return keccak256(bytes(name));\n } else {\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\n bytes32 hashedName = _hashedName;\n if (hashedName != 0) {\n return hashedName;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\n */\n function _EIP712VersionHash() internal view returns (bytes32) {\n string memory version = _EIP712Version();\n if (bytes(version).length > 0) {\n return keccak256(bytes(version));\n } else {\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\n bytes32 hashedVersion = _hashedVersion;\n if (hashedVersion != 0) {\n return hashedVersion;\n } else {\n return keccak256(\"\");\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@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/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC1155/IERC1155.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC20/IERC20.sol\";\n" + }, + "@openzeppelin/contracts/interfaces/IERC2981.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981 is IERC165 {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/IERC721.sol\";\n" + }, + "@openzeppelin/contracts/proxy/Clones.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create opcode, which should never revert.\n */\n function clone(address implementation) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create(0, 0x09, 0x37)\n }\n require(instance != address(0), \"ERC1167: create failed\");\n }\n\n /**\n * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n *\n * This function uses the create2 opcode and a `salt` to deterministically deploy\n * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n * the clones cannot be deployed twice at the same address.\n */\n function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n /// @solidity memory-safe-assembly\n assembly {\n // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n // of the `implementation` address with the bytecode before the address.\n mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n instance := create2(0, 0x09, 0x37, salt)\n }\n require(instance != address(0), \"ERC1167: create2 failed\");\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt,\n address deployer\n ) internal pure returns (address predicted) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(add(ptr, 0x38), deployer)\n mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n mstore(add(ptr, 0x14), implementation)\n mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n mstore(add(ptr, 0x58), salt)\n mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n predicted := keccak256(add(ptr, 0x43), 0x55)\n }\n }\n\n /**\n * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n */\n function predictDeterministicAddress(\n address implementation,\n bytes32 salt\n ) internal view returns (address predicted) {\n return predictDeterministicAddress(implementation, salt, address(this));\n }\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/ERC1155/utils/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n }\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/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/ERC721/utils/ERC721Holder.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Receiver.sol\";\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n /**\n * @dev See {IERC721Receiver-onERC721Received}.\n *\n * Always returns `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n return this.onERC721Received.selector;\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/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/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/ERC165Checker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n // As per the EIP-165 spec, no interface should ever match 0xffffffff\n bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n /**\n * @dev Returns true if `account` supports the {IERC165} interface.\n */\n function supportsERC165(address account) internal view returns (bool) {\n // Any contract that implements ERC165 must explicitly indicate support of\n // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n return\n supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) &&\n !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);\n }\n\n /**\n * @dev Returns true if `account` supports the interface defined by\n * `interfaceId`. Support for {IERC165} itself is queried automatically.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n // query support of both ERC165 as per the spec and support of _interfaceId\n return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);\n }\n\n /**\n * @dev Returns a boolean array where each value corresponds to the\n * interfaces passed in and whether they're supported or not. This allows\n * you to batch check interfaces for a contract where your expectation\n * is that some interfaces may not be supported.\n *\n * See {IERC165-supportsInterface}.\n *\n * _Available since v3.4._\n */\n function getSupportedInterfaces(\n address account,\n bytes4[] memory interfaceIds\n ) internal view returns (bool[] memory) {\n // an array of booleans corresponding to interfaceIds and whether they're supported or not\n bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n // query support of ERC165 itself\n if (supportsERC165(account)) {\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);\n }\n }\n\n return interfaceIdsSupported;\n }\n\n /**\n * @dev Returns true if `account` supports all the interfaces defined in\n * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n *\n * Batch-querying can lead to gas savings by skipping repeated checks for\n * {IERC165} support.\n *\n * See {IERC165-supportsInterface}.\n */\n function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n // query support of ERC165 itself\n if (!supportsERC165(account)) {\n return false;\n }\n\n // query support of each interface in interfaceIds\n for (uint256 i = 0; i < interfaceIds.length; i++) {\n if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {\n return false;\n }\n }\n\n // all interfaces supported\n return true;\n }\n\n /**\n * @notice Query if a contract implements an interface, does not check ERC165 support\n * @param account The address of the contract to query for support of an interface\n * @param interfaceId The interface identifier, as specified in ERC-165\n * @return true if the contract at account indicates support of the interface with\n * identifier interfaceId, false otherwise\n * @dev Assumes that account contains a contract that supports ERC165, otherwise\n * the behavior of this method is undefined. This precondition can be checked\n * with {supportsERC165}.\n *\n * Some precompiled contracts will falsely indicate support for a given interface, so caution\n * should be exercised when using this function.\n *\n * Interface identification is specified in ERC-165.\n */\n function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {\n // prepare call\n bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n\n // perform static call\n bool success;\n uint256 returnSize;\n uint256 returnValue;\n assembly {\n success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)\n returnSize := returndatasize()\n returnValue := mload(0x00)\n }\n\n return success && returnSize >= 0x20 && returnValue > 0;\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/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n unchecked {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator.\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b <= a, errorMessage);\n return a - b;\n }\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a / b;\n }\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n unchecked {\n require(b > 0, errorMessage);\n return a % b;\n }\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" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```solidity\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n bytes32[] memory store = _values(set._inner);\n bytes32[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Asset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable,\n IAccessControlUpgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable,\n ERC1155Upgradeable,\n IERC1155Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable,\n IERC1155MetadataURIUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {\n MultiRoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol\";\nimport {\n OperatorFiltererUpgradeable\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\n\ncontract Asset is\n IAsset,\n Initializable,\n ERC2771Handler,\n ERC1155BurnableUpgradeable,\n AccessControlUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n OperatorFiltererUpgradeable,\n MultiRoyaltyDistributor\n{\n using TokenIdUtils for uint256;\n\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n bytes32 public constant MODERATOR_ROLE = keccak256(\"MODERATOR_ROLE\");\n\n // mapping of ipfs metadata token hash to token id\n mapping(string => uint256) public hashUsed;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n function initialize(\n address forwarder,\n address assetAdmin,\n string memory baseUri,\n address commonSubscription,\n address payable defaultRecipient,\n uint16 defaultBps,\n address _manager\n ) external initializer {\n _setBaseURI(baseUri);\n __AccessControl_init();\n __ERC1155Supply_init();\n __ERC2771Handler_initialize(forwarder);\n __ERC1155Burnable_init();\n _grantRole(DEFAULT_ADMIN_ROLE, assetAdmin);\n __OperatorFilterer_init(commonSubscription, true);\n __MultiRoyaltyDistributor_init(defaultRecipient, defaultBps, _manager);\n }\n\n /// @notice Mint new tokens\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external onlyRole(MINTER_ROLE) {\n _setMetadataHash(id, metadataHash);\n _mint(to, id, amount, \"\");\n address creator = id.getCreatorAddress();\n _setTokenRoyalties(id, _defaultRoyaltyBPS, payable(creator), creator);\n }\n\n /// @notice Mint new tokens with catalyst tier chosen by the creator\n /// @dev Only callable by the minter role\n /// @param to The address of the recipient\n /// @param ids The ids of the tokens to mint\n /// @param amounts The amounts of the tokens to mint\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external onlyRole(MINTER_ROLE) {\n require(ids.length == metadataHashes.length, \"Asset: ids and metadataHash length mismatch\");\n require(ids.length == amounts.length, \"Asset: ids and amounts length mismatch\");\n for (uint256 i = 0; i < ids.length; i++) {\n _setMetadataHash(ids[i], metadataHashes[i]);\n }\n _mintBatch(to, ids, amounts, \"\");\n for (uint256 i; i < ids.length; i++) {\n address creator = ids[i].getCreatorAddress();\n _setTokenRoyalties(ids[i], _defaultRoyaltyBPS, payable(creator), creator);\n }\n }\n\n /// @notice Burn a token from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @param account The account to burn tokens from\n /// @param id The token id to burn\n /// @param amount The amount of tokens to burn\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burn a batch of tokens from a given account\n /// @dev Only the minter role can burn tokens\n /// @dev This function was added with token recycling and bridging in mind but may have other use cases\n /// @dev The length of the ids and amounts arrays must be the same\n /// @param account The account to burn tokens from\n /// @param ids An array of token ids to burn\n /// @param amounts An array of amounts of tokens to burn\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @dev The metadata hash should be the IPFS CIDv1 base32 encoded hash\n /// @param tokenId The token id to set URI for\n /// @param metadata The new URI for asset's metadata\n function setTokenURI(uint256 tokenId, string memory metadata) external onlyRole(MODERATOR_ROLE) {\n _setURI(tokenId, metadata);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n function getTokenIdByMetadataHash(string memory metadataHash) public view returns (uint256) {\n return hashUsed[metadataHash];\n }\n\n function _setMetadataHash(uint256 tokenId, string memory metadataHash) internal {\n if (hashUsed[metadataHash] != 0) {\n require(hashUsed[metadataHash] == tokenId, \"Asset: not allowed to reuse metadata hash\");\n } else {\n hashUsed[metadataHash] = tokenId;\n _setURI(tokenId, metadataHash);\n }\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Asset: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param id the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 id)\n public\n view\n virtual\n override(ERC1155Upgradeable, AccessControlUpgradeable, MultiRoyaltyDistributor)\n returns (bool)\n {\n return\n id == type(IERC165Upgradeable).interfaceId ||\n id == type(IERC1155Upgradeable).interfaceId ||\n id == type(IERC1155MetadataURIUpgradeable).interfaceId ||\n id == type(IAccessControlUpgradeable).interfaceId ||\n id == 0x572b6c05; // ERC2771\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\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 onlyAllowedOperator(from) {\n super.safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved)\n public\n virtual\n override\n onlyAllowedOperatorApproval(operator)\n {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) public virtual override onlyAllowedOperator(from) {\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 /// @notice could be used to deploy splitter and set tokens royalties\n /// @param tokenId the id of the token for which the EIP2981 royalty is set for.\n /// @param royaltyBPS should be defult EIP2981 roayaltie.\n /// @param recipient the royalty recipient for the splitter of the creator.\n /// @param creator the creactor of the tokens.\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setTokenRoyalties(tokenId, royaltyBPS, recipient, creator);\n }\n\n /// @notice sets default royalty bps for EIP2981\n /// @dev only owner can call.\n /// @param defaultBps royalty bps base 10000\n function setDefaultRoyaltyBps(uint16 defaultBps) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setDefaultRoyaltyBps(defaultBps);\n }\n\n /// @notice sets default royalty receiver for EIP2981\n /// @dev only owner can call.\n /// @param defaultReceiver address of default royalty recipient.\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external onlyRole(DEFAULT_ADMIN_ROLE) {\n _setDefaultRoyaltyReceiver(defaultReceiver);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\nimport {IAssetCreate} from \"./interfaces/IAssetCreate.sol\";\n\n/// @title AssetCreate\n/// @author The Sandbox\n/// @notice User-facing contract for creating new assets\ncontract AssetCreate is IAssetCreate, Initializable, ERC2771Handler, EIP712Upgradeable, AccessControlUpgradeable {\n using TokenIdUtils for uint256;\n\n IAsset private assetContract;\n ICatalyst private catalystContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator address to creator nonce, a nonce is incremented every time a creator mints a new token\n mapping(address => uint16) public creatorNonces;\n mapping(address => uint16) public signatureNonces;\n\n bytes32 public constant SPECIAL_MINTER_ROLE = keccak256(\"SPECIAL_MINTER_ROLE\");\n bytes32 public constant MINT_TYPEHASH =\n keccak256(\"Mint(address creator,uint16 nonce,uint8 tier,uint256 amount,bool revealed,string metadataHash)\");\n bytes32 public constant MINT_BATCH_TYPEHASH =\n keccak256(\n \"MintBatch(address creator,uint16 nonce,uint8[] tiers,uint256[] amounts,bool[] revealed,string[] metadataHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _catalystContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n catalystContract = ICatalyst(_catalystContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_initialize(_forwarder);\n __EIP712_init(_name, _version);\n __AccessControl_init();\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Create a new asset\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n // burn catalyst of a given tier\n catalystContract.burnFrom(creator, tier, amount);\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit AssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Create multiple assets at once\n /// @param signature A signature generated by TSB\n /// @param tiers The tiers of the assets to mint\n /// @param amounts The amounts of the assets to mint\n /// @param metadataHashes The metadata hashes of the assets to mint\n function createMultipleAssets(\n bytes memory signature,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes,\n address creator\n ) external {\n require(\n authValidator.verify(\n signature,\n _hashBatchMint(creator, signatureNonces[_msgSender()]++, tiers, amounts, revealed, metadataHashes)\n ),\n \"Invalid signature\"\n );\n\n require(tiers.length == amounts.length, \"Arrays must be same length\");\n require(amounts.length == metadataHashes.length, \"Arrays must be same length\");\n require(metadataHashes.length == revealed.length, \"Arrays must be same length\");\n\n uint256[] memory tokenIds = new uint256[](tiers.length);\n uint256[] memory tiersToBurn = new uint256[](tiers.length);\n for (uint256 i = 0; i < tiers.length; i++) {\n tiersToBurn[i] = tiers[i];\n tokenIds[i] = TokenIdUtils.generateTokenId(\n creator,\n tiers[i],\n ++creatorNonces[creator],\n revealed[i] ? 1 : 0,\n false\n );\n }\n\n catalystContract.burnBatchFrom(creator, tiersToBurn, amounts);\n\n assetContract.mintBatch(creator, tokenIds, amounts, metadataHashes);\n emit AssetBatchMinted(creator, tokenIds, tiers, amounts, metadataHashes, revealed);\n }\n\n /// @notice Create special assets, like TSB exclusive tokens\n /// @dev Only callable by the special minter\n /// @param signature A signature generated by TSB\n /// @param tier The tier of the asset to mint\n /// @param amount The amount of the asset to mint\n /// @param metadataHash The metadata hash of the asset to mint\n function createSpecialAsset(\n bytes memory signature,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash,\n address creator\n ) external onlyRole(SPECIAL_MINTER_ROLE) {\n require(\n authValidator.verify(\n signature,\n _hashMint(creator, signatureNonces[_msgSender()]++, tier, amount, revealed, metadataHash)\n ),\n \"Invalid signature\"\n );\n\n uint256 tokenId =\n TokenIdUtils.generateTokenId(creator, tier, ++creatorNonces[creator], revealed ? 1 : 0, false);\n\n assetContract.mint(creator, tokenId, amount, metadataHash);\n emit SpecialAssetMinted(creator, tokenId, tier, amount, metadataHash, revealed);\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the catalyst contract address\n /// @return The catalyst contract address\n function getCatalystContract() external view returns (address) {\n return address(catalystContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Creates a hash of the mint data\n /// @param creator The address of the creator\n /// @param tier The tier of the asset\n /// @param amount The amount of copies to mint\n /// @param metadataHash The metadata hash of the asset\n /// @return digest The hash of the mint data\n function _hashMint(\n address creator,\n uint16 nonce,\n uint8 tier,\n uint256 amount,\n bool revealed,\n string calldata metadataHash\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_TYPEHASH,\n creator,\n nonce,\n tier,\n amount,\n revealed,\n keccak256((abi.encodePacked(metadataHash)))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the mint batch data\n /// @param creator The address of the creator\n /// @param tiers The tiers of the assets\n /// @param amounts The amounts of copies to mint\n /// @param metadataHashes The metadata hashes of the assets\n /// @return digest The hash of the mint batch data\n function _hashBatchMint(\n address creator,\n uint16 nonce,\n uint8[] calldata tiers,\n uint256[] calldata amounts,\n bool[] calldata revealed,\n string[] calldata metadataHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n MINT_BATCH_TYPEHASH,\n creator,\n nonce,\n keccak256(abi.encodePacked(tiers)),\n keccak256(abi.encodePacked(amounts)),\n keccak256(abi.encodePacked(revealed)),\n _encodeHashes(metadataHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {EIP712Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {TokenIdUtils} from \"./libraries/TokenIdUtils.sol\";\nimport {AuthSuperValidator} from \"./AuthSuperValidator.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {IAsset} from \"./interfaces/IAsset.sol\";\nimport {IAssetReveal} from \"./interfaces/IAssetReveal.sol\";\n\n/// @title AssetReveal\n/// @author The Sandbox\n/// @notice Contract for burning and revealing assets\ncontract AssetReveal is IAssetReveal, Initializable, AccessControlUpgradeable, ERC2771Handler, EIP712Upgradeable {\n using TokenIdUtils for uint256;\n IAsset private assetContract;\n AuthSuperValidator private authValidator;\n\n // mapping of creator to asset id to asset's reveal nonce\n mapping(address => mapping(uint256 => uint16)) internal revealIds;\n\n // mapping for showing whether a revealHash has been used\n // revealHashes are generated by the TSB backend from reveal burn events and are used for reveal minting\n mapping(bytes32 => bool) internal revealHashesUsed;\n\n bytes32 public constant REVEAL_TYPEHASH =\n keccak256(\n \"Reveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n bytes32 public constant BATCH_REVEAL_TYPEHASH =\n keccak256(\n \"BatchReveal(address recipient,uint256[] prevTokenIds,uint256[][] amounts,string[][] metadataHashes,bytes32[][] revealHashes)\"\n );\n bytes32 public constant INSTANT_REVEAL_TYPEHASH =\n keccak256(\n \"InstantReveal(address recipient,uint256 prevTokenId,uint256[] amounts,string[] metadataHashes,bytes32[] revealHashes)\"\n );\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n /// @notice Initialize the contract\n /// @param _assetContract The address of the asset contract\n /// @param _authValidator The address of the AuthSuperValidator contract\n /// @param _forwarder The address of the forwarder contract\n function initialize(\n string memory _name,\n string memory _version,\n address _assetContract,\n address _authValidator,\n address _forwarder,\n address _defaultAdmin\n ) public initializer {\n assetContract = IAsset(_assetContract);\n authValidator = AuthSuperValidator(_authValidator);\n __ERC2771Handler_initialize(_forwarder);\n __EIP712_init(_name, _version);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n }\n\n /// @notice Reveal an asset to view its abilities and enhancements\n /// @dev the reveal mechanism works through burning the asset and minting a new one with updated tokenId\n /// @param tokenId the tokenId of id idasset to reveal\n /// @param amount the amount of tokens to reveal\n function revealBurn(uint256 tokenId, uint256 amount) external {\n _burnAsset(tokenId, amount);\n emit AssetRevealBurn(_msgSender(), tokenId, amount);\n }\n\n /// @notice Burn multiple assets to be able to reveal them later\n /// @dev Can be used to burn multiple copies of the same token id, each copy will be revealed separately\n /// @param tokenIds the tokenIds of the assets to burn\n /// @param amounts the amounts of the assets to burn\n function revealBatchBurn(uint256[] calldata tokenIds, uint256[] calldata amounts) external {\n _burnAssetBatch(tokenIds, amounts);\n emit AssetRevealBatchBurn(_msgSender(), tokenIds, amounts);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signature created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (length reflects the number of types of reveal tokens and must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for revealed asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function revealMint(\n bytes memory signature,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealMint signature\"\n );\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Mint multiple assets with revealed abilities and enhancements\n /// @dev Can be used to reveal multiple copies of the same token id\n /// @param signature Signatures created on the TSB backend containing REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenIds The tokenId of the unrevealed asset\n /// @param amounts The amount of assets to reveal (must be equal to the length of revealHashes)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes Array of revealHash arrays providing random bytes32 generated by the TSB backend for each new tokenId\n function revealBatchMint(\n bytes calldata signature,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) external {\n require(prevTokenIds.length == amounts.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid metadataHashes length\");\n require(prevTokenIds.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashBatchReveal(_msgSender(), prevTokenIds, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid revealBatchMint signature\"\n );\n uint256[][] memory newTokenIds = new uint256[][](prevTokenIds.length);\n for (uint256 i = 0; i < prevTokenIds.length; i++) {\n newTokenIds[i] = _revealAsset(prevTokenIds[i], metadataHashes[i], amounts[i], revealHashes[i]);\n }\n emit AssetRevealBatchMint(_msgSender(), prevTokenIds, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Reveal assets to view their abilities and enhancements and mint them in a single transaction\n /// @dev Should be used where it is not required to keep the metadata secret, e.g. mythical assets where users select their desired abilities and enhancements\n /// @param signature Signature created on the TSB backend containing INSTANT_REVEAL_TYPEHASH and associated data, must be signed by authorized signer\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param burnAmount The amount of assets to burn\n /// @param amounts The amount of assets to reveal (sum must be equal to the burnAmount)\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param revealHashes A revealHash array providing a random bytes32 generated by the TSB backend for each new tokenId\n function burnAndReveal(\n bytes memory signature,\n uint256 prevTokenId,\n uint256 burnAmount,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) external {\n require(amounts.length == metadataHashes.length, \"AssetReveal: Invalid amounts length\");\n require(amounts.length == revealHashes.length, \"AssetReveal: Invalid revealHashes length\");\n require(\n authValidator.verify(\n signature,\n _hashInstantReveal(_msgSender(), prevTokenId, amounts, metadataHashes, revealHashes)\n ),\n \"AssetReveal: Invalid burnAndReveal signature\"\n );\n _burnAsset(prevTokenId, burnAmount);\n uint256[] memory newTokenIds = _revealAsset(prevTokenId, metadataHashes, amounts, revealHashes);\n emit AssetRevealMint(_msgSender(), prevTokenId, amounts, newTokenIds, revealHashes);\n }\n\n /// @notice Generate new tokenIds for revealed assets and mint them\n /// @param prevTokenId The tokenId of the unrevealed asset\n /// @param metadataHashes The array of hashes for asset metadata\n /// @param amounts The array of amounts to mint\n function _revealAsset(\n uint256 prevTokenId,\n string[] calldata metadataHashes,\n uint256[] calldata amounts,\n bytes32[] calldata revealHashes\n ) internal returns (uint256[] memory) {\n uint256[] memory newTokenIds = getRevealedTokenIds(metadataHashes, prevTokenId);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n require(revealHashesUsed[revealHashes[i]] == false, \"AssetReveal: RevealHash already used\");\n revealHashesUsed[revealHashes[i]] = true;\n }\n if (newTokenIds.length == 1) {\n assetContract.mint(_msgSender(), newTokenIds[0], amounts[0], metadataHashes[0]);\n } else {\n assetContract.mintBatch(_msgSender(), newTokenIds, amounts, metadataHashes);\n }\n return newTokenIds;\n }\n\n /// @notice Burns an asset to be able to reveal it later\n /// @param tokenId the tokenId of the asset to burn\n /// @param amount the amount of the asset to burn\n function _burnAsset(uint256 tokenId, uint256 amount) internal {\n _verifyBurnData(tokenId, amount);\n assetContract.burnFrom(_msgSender(), tokenId, amount);\n }\n\n function _burnAssetBatch(uint256[] calldata tokenIds, uint256[] calldata amounts) internal {\n require(tokenIds.length == amounts.length, \"AssetReveal: Invalid input\");\n for (uint256 i = 0; i < tokenIds.length; i++) {\n _verifyBurnData(tokenIds[i], amounts[i]);\n }\n assetContract.burnBatchFrom(_msgSender(), tokenIds, amounts);\n }\n\n function _verifyBurnData(uint256 tokenId, uint256 amount) internal pure {\n IAsset.AssetData memory data = tokenId.getData();\n require(!data.revealed, \"AssetReveal: Asset is already revealed\");\n require(amount > 0, \"AssetReveal: Burn amount should be greater than 0\");\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The address of the recipient\n /// @param prevTokenId The unrevealed token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashInstantReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n INSTANT_REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed token\n /// @param prevTokenId The previous token id\n /// @param amounts The amount of tokens to mint\n /// @param metadataHashes The array of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for revealing this particular prevTokenId (length corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashReveal(\n address recipient,\n uint256 prevTokenId,\n uint256[] calldata amounts,\n string[] calldata metadataHashes,\n bytes32[] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n REVEAL_TYPEHASH,\n recipient,\n prevTokenId,\n keccak256(abi.encodePacked(amounts)),\n _encodeHashes(metadataHashes),\n keccak256(abi.encodePacked(revealHashes))\n )\n )\n );\n }\n\n /// @notice Creates a hash of the reveal data\n /// @param recipient The intended recipient of the revealed tokens\n /// @param prevTokenIds The previous token id\n /// @param amounts The amounts of tokens to mint\n /// @param metadataHashes The arrays of hashes for new asset metadata\n /// @param revealHashes The revealHashes used for these prevTokenIds, (lengths corresponds to the new tokenIds)\n /// @return digest The hash of the reveal data\n function _hashBatchReveal(\n address recipient,\n uint256[] calldata prevTokenIds,\n uint256[][] calldata amounts,\n string[][] calldata metadataHashes,\n bytes32[][] calldata revealHashes\n ) internal view returns (bytes32 digest) {\n digest = _hashTypedDataV4(\n keccak256(\n abi.encode(\n BATCH_REVEAL_TYPEHASH,\n recipient,\n keccak256(abi.encodePacked(prevTokenIds)),\n _encodeBatchAmounts(amounts),\n _encodeBatchHashes(metadataHashes),\n _encodeBatchRevealHashes(revealHashes)\n )\n )\n );\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeHashes(string[] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = keccak256((abi.encodePacked(metadataHashes[i])));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param metadataHashes The hashes of the metadata\n /// @return encodedHashes The encoded hashes of the metadata\n function _encodeBatchHashes(string[][] memory metadataHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n encodedHashes[i] = _encodeHashes(metadataHashes[i]);\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the hashes of the metadata for signature verification\n /// @param revealHashes The revealHashes\n /// @return encodedRevealHashes The encoded hashes of the metadata\n function _encodeBatchRevealHashes(bytes32[][] memory revealHashes) internal pure returns (bytes32) {\n bytes32[] memory encodedHashes = new bytes32[](revealHashes.length);\n for (uint256 i = 0; i < revealHashes.length; i++) {\n encodedHashes[i] = keccak256(abi.encodePacked(revealHashes[i]));\n }\n return keccak256(abi.encodePacked(encodedHashes));\n }\n\n /// @notice Encodes the amounts of the tokens for signature verification\n /// @param amounts The amounts of the tokens\n /// @return encodedAmounts The encoded amounts of the tokens\n function _encodeBatchAmounts(uint256[][] memory amounts) internal pure returns (bytes32) {\n bytes32[] memory encodedAmounts = new bytes32[](amounts.length);\n for (uint256 i = 0; i < amounts.length; i++) {\n encodedAmounts[i] = keccak256(abi.encodePacked(amounts[i]));\n }\n return keccak256(abi.encodePacked(encodedAmounts));\n }\n\n /// @notice Checks if each metadatahash has been used before to either get the tokenId that was already created for it or generate a new one if it hasn't\n /// @dev This function also validates that we're not trying to reveal a tokenId that has already been revealed\n /// @param metadataHashes The hashes of the metadata\n /// @param prevTokenId The previous token id from which the assets are revealed\n /// @return tokenIdArray The array of tokenIds to mint\n function getRevealedTokenIds(string[] calldata metadataHashes, uint256 prevTokenId)\n internal\n returns (uint256[] memory)\n {\n IAsset.AssetData memory data = prevTokenId.getData();\n require(!data.revealed, \"AssetReveal: already revealed\");\n uint256[] memory tokenIdArray = new uint256[](metadataHashes.length);\n for (uint256 i = 0; i < metadataHashes.length; i++) {\n uint256 tokenId = assetContract.getTokenIdByMetadataHash(metadataHashes[i]);\n if (tokenId == 0) {\n uint16 revealNonce = ++revealIds[data.creator][prevTokenId];\n tokenId = TokenIdUtils.generateTokenId(\n data.creator,\n data.tier,\n data.creatorNonce,\n revealNonce,\n data.bridged\n );\n }\n tokenIdArray[i] = tokenId;\n }\n return tokenIdArray;\n }\n\n /// @notice Get the status of a revealHash\n /// @return Whether it has been used\n function revealHashUsed(bytes32 revealHash) external view returns (bool) {\n return revealHashesUsed[revealHash];\n }\n\n /// @notice Get the asset contract address\n /// @return The asset contract address\n function getAssetContract() external view returns (address) {\n return address(assetContract);\n }\n\n /// @notice Get the auth validator address\n /// @return The auth validator address\n function getAuthValidator() external view returns (address) {\n return address(authValidator);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"AssetReveal: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address sender) {\n return ERC2771Handler._msgSender();\n }\n\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/AuthSuperValidator.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\n/// @title AuthSuperValidator\n/// @author The Sandbox\n/// @notice This contract is used to validate the signatures of the backend, each contract can have a separate signer assigned\ncontract AuthSuperValidator is AccessControl {\n mapping(address => address) private _signers;\n\n /// @dev Constructor\n /// @param admin Address of the admin that will be able to grant roles\n constructor(address admin) {\n _grantRole(DEFAULT_ADMIN_ROLE, admin);\n }\n\n /// @notice Sets the signer for a contract\n /// @dev Only the admin can call this function\n /// @param contractAddress Address of the contract to set the signer for\n /// @param signer Address of the signer\n function setSigner(address contractAddress, address signer) public onlyRole(DEFAULT_ADMIN_ROLE) {\n _signers[contractAddress] = signer;\n }\n\n /// @notice Gets the signer for a contract\n /// @param contractAddress Address of the contract to get the signer for\n /// @return address of the signer\n function getSigner(address contractAddress) public view returns (address) {\n return _signers[contractAddress];\n }\n\n /// @notice Takes the signature and the digest and returns if the signer has a backend signer role assigned\n /// @dev Multipurpose function that can be used to verify signatures with different digests\n /// @param signature Signature hash\n /// @param digest Digest hash\n /// @return bool\n function verify(bytes memory signature, bytes32 digest) public view returns (bool) {\n address signer = _signers[_msgSender()];\n require(signer != address(0), \"AuthSuperValidator: signer not set\");\n address recoveredSigner = ECDSA.recover(digest, signature);\n return recoveredSigner == signer;\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771Handler,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public tokenCount;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= tokenCount, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_initialize(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n\n _setURI(i + 1, _catalystIpfsCID[i]);\n unchecked {tokenCount++;}\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= tokenCount, \"INVALID_CATALYST_ID\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param catalystId The catalyst id to add\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(uint256 catalystId, string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(catalystId > tokenCount, \"Catalyst: invalid catalyst id\");\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n tokenCount++;\n ERC1155URIStorageUpgradeable._setURI(catalystId, ipfsCID);\n emit NewCatalystTypeAdded(catalystId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return\n ERC1155Upgradeable.supportsInterface(interfaceId) ||\n AccessControlUpgradeable.supportsInterface(interfaceId) ||\n RoyaltyDistributor.supportsInterface(interfaceId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/ERC2771Handler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n/// with an initializer for proxies and a mutable forwarder\n\nabstract contract ERC2771Handler {\n address internal _trustedForwarder;\n\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAsset {\n // AssetData reflects the asset tokenId structure\n // Refer to TokenIdUtils.sol\n struct AssetData {\n uint256 tokenId;\n address creator;\n uint256 amount;\n uint8 tier;\n uint16 creatorNonce;\n bool revealed;\n string metadataHash;\n bool bridged;\n }\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n\n // Functions\n function mint(\n address to,\n uint256 id,\n uint256 amount,\n string memory metadataHash\n ) external;\n\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n string[] memory metadataHashes\n ) external;\n\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n function getTokenIdByMetadataHash(string memory metadataHash) external view returns (uint256);\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetCreate {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event SpecialAssetMinted(\n address indexed creator,\n uint256 tokenId,\n uint16 tier,\n uint256 amount,\n string metadataHash,\n bool revealed\n );\n event AssetBatchMinted(\n address indexed creator,\n uint256[] tokenIds,\n uint8[] tiers,\n uint256[] amounts,\n string[] metadataHashes,\n bool[] revealed\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/IAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface IAssetReveal {\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event AssetRevealBurn(address revealer, uint256 unrevealedTokenId, uint256 amount);\n event AssetRevealBatchBurn(address revealer, uint256[] unrevealedTokenIds, uint256[] amounts);\n event AssetRevealMint(\n address recipient,\n uint256 unrevealedTokenId,\n uint256[] amounts,\n uint256[] newTokenIds,\n bytes32[] revealHashes\n );\n event AssetRevealBatchMint(\n address recipient,\n uint256[] unrevealedTokenIds,\n uint256[][] amounts,\n uint256[][] newTokenIds,\n bytes32[][] revealHashes\n );\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param catalystId The catalyst id to add\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(uint256 catalystId, string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/libraries/TokenIdUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\n\nlibrary TokenIdUtils {\n // Layer masks\n uint256 public constant TIER_MASK = 0xFF;\n uint256 public constant NONCE_MASK = 0x3FF;\n uint256 public constant REVEAL_NONCE_MASK = 0x3FF;\n uint256 public constant BRIDGED_MASK = 0x1;\n\n // Bit shifts\n uint256 public constant CREATOR_SHIFT = 0;\n uint256 public constant TIER_SHIFT = 160;\n uint256 public constant NONCE_SHIFT = 168;\n uint256 public constant REVEAL_NONCE_SHIFT = 185;\n uint256 public constant BRIDGED_SHIFT = 201;\n\n /// @notice Generates a token id for a given asset\n /// @dev The token id is generated by concatenating the following fields:\n /// @dev creator address, chain index, tier, asset nonce, reveal nonce and bridged boolean\n /// @dev The first 160 bits are the creator address\n /// @dev The next 8 bits are the chain index\n /// @dev The next 8 bits are the tier\n /// @dev The next 16 bits are the asset nonce\n /// @dev The next 16 bits are assets reveal nonce.\n /// @param creator The address of the creator of the asset\n /// @param tier The tier of the asset determined by the catalyst used to create it\n /// @param creatorNonce The nonce of the asset creator\n /// @param revealNonce The reveal nonce of the asset\n /// @param bridged Whether the asset is bridged or not\n /// @return tokenId The generated token id\n function generateTokenId(\n address creator,\n uint8 tier,\n uint16 creatorNonce,\n uint16 revealNonce,\n bool bridged\n ) internal pure returns (uint256 tokenId) {\n uint160 creatorAddress = uint160(creator);\n\n tokenId = tokenId =\n uint256(creatorAddress) |\n (uint256(tier) << TIER_SHIFT) |\n (uint256(creatorNonce) << NONCE_SHIFT) |\n (uint256(revealNonce) << REVEAL_NONCE_SHIFT) |\n (uint256(bridged ? 1 : 0) << BRIDGED_SHIFT);\n\n return tokenId;\n }\n\n /// @notice Extracts the creator address from a given token id\n /// @param tokenId The token id to extract the creator address from\n /// @return creator The asset creator address\n function getCreatorAddress(uint256 tokenId) internal pure returns (address creator) {\n creator = address(uint160(tokenId));\n return creator;\n }\n\n /// @notice Extracts the tier from a given token id\n /// @param tokenId The token id to extract the tier from\n /// @return tier The asset tier, determined by the catalyst used to create it\n function getTier(uint256 tokenId) internal pure returns (uint8 tier) {\n tier = uint8((tokenId >> TIER_SHIFT) & TIER_MASK);\n return tier;\n }\n\n /// @notice Extracts the revealed flag from a given token id\n /// @param tokenId The token id to extract the revealed flag from\n /// @return isRevealed Whether the asset is revealed or not\n function isRevealed(uint256 tokenId) internal pure returns (bool) {\n uint16 revealNonce = getRevealNonce(tokenId);\n return revealNonce != 0;\n }\n\n /// @notice Extracts the asset nonce from a given token id\n /// @param tokenId The token id to extract the asset nonce from\n /// @return creatorNonce The asset creator nonce\n function getCreatorNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 creatorNonce = uint16((tokenId >> NONCE_SHIFT) & NONCE_MASK);\n return creatorNonce;\n }\n\n /// @notice Extracts the abilities and enhancements hash from a given token id\n /// @param tokenId The token id to extract reveal nonce from\n /// @return revealNonce The reveal nonce of the asset\n function getRevealNonce(uint256 tokenId) internal pure returns (uint16) {\n uint16 revealNonce = uint16((tokenId >> REVEAL_NONCE_SHIFT) & REVEAL_NONCE_MASK);\n return revealNonce;\n }\n\n /// @notice Extracts the bridged flag from a given token id\n /// @param tokenId The token id to extract the bridged flag from\n /// @return bridged Whether the asset is bridged or not\n function isBridged(uint256 tokenId) internal pure returns (bool) {\n bool bridged = ((tokenId >> BRIDGED_SHIFT) & BRIDGED_MASK) == 1;\n return bridged;\n }\n\n /// @notice Extracts the asset data from a given token id\n /// @dev Created to limit the number of functions that need to be called when revealing an asset\n /// @param tokenId The token id to extract the asset data from\n function getData(uint256 tokenId) internal pure returns (IAsset.AssetData memory data) {\n data.creator = getCreatorAddress(tokenId);\n data.tier = getTier(tokenId);\n data.revealed = isRevealed(tokenId);\n data.creatorNonce = getCreatorNonce(tokenId);\n data.bridged = isBridged(tokenId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/FallBackRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n FallbackRegistry\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/FallbackRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAsset.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function\n\nimport {Asset} from \"../Asset.sol\";\nimport {\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol\";\n\ncontract MockAsset is Asset {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filtering\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetCreate.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetCreate} from \"../AssetCreate.sol\";\n\ncontract MockAssetCreate is AssetCreate {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockAssetReveal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n// mock the asset contract to test the _msgData() function to satisfy the coverage\n\nimport {AssetReveal} from \"../AssetReveal.sol\";\n\ncontract MockAssetReveal is AssetReveal {\n function msgData() external view returns (bytes memory) {\n return _msgData();\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketplace.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockMarketplace\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/MockMarketplace.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace1\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace2.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace2\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace3.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace3\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMarketPlace4.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockERC1155MarketPlace4\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockMinter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IAsset} from \"../interfaces/IAsset.sol\";\nimport {TokenIdUtils} from \"../libraries/TokenIdUtils.sol\";\n\ncontract MockMinter {\n using TokenIdUtils for uint256;\n\n IAsset public assetContract;\n\n mapping(address => uint16) public creatorNonces;\n\n event Minted(uint256 tokenId, uint256 amount);\n\n constructor(address _assetContract) {\n assetContract = IAsset(_assetContract);\n }\n\n /// @dev Mints a specified number of unrevealed copies of specific tier\n function mintAsset(\n address recipient,\n uint256 amount,\n uint8 tier,\n bool revealed,\n string calldata metadataHash\n ) public {\n // increment nonce\n unchecked {creatorNonces[msg.sender]++;}\n // get current creator nonce\n uint16 creatorNonce = creatorNonces[msg.sender];\n uint256 tokenId = TokenIdUtils.generateTokenId(msg.sender, tier, creatorNonce, revealed ? 1 : 0, false);\n\n assetContract.mint(recipient, tokenId, amount, metadataHash);\n emit Minted(tokenId, amount);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockOperatorFilterRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockOperatorFilterSubscription.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n MockOperatorFilterSubscription\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyEngineV1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n RoyaltyEngineV1\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyManager.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyManager} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltyRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {\n RoyaltyRegistry\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/RoyaltySplitter.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltySplitter} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol\";\n\n/* solhint-disable-next-line no-empty-blocks*/\ncontract MockSplitter is RoyaltySplitter {\n\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/TestERC20.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {TestERC20} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC20.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace1 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace2.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace2 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace3.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace3 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockMarketPlace4.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {IERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC1155Upgradeable.sol\";\nimport {ERC1155Receiver} from \"@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol\";\nimport {ERC721Holder} from \"@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol\";\n\ncontract MockERC1155MarketPlace4 is ERC1155Receiver, ERC721Holder {\n bytes4 private constant ERC1155_IS_RECEIVER = 0x4e2312e0;\n bytes4 private constant ERC1155_RECEIVED = 0xf23a6e61;\n bytes4 private constant ERC1155_BATCH_RECEIVED = 0xbc197c81;\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param amount amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function transferTokenForERC1155(\n address asset,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeTransferFrom(from, to, id, amount, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @param asset the contract address on which the token transfer will take place\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param amounts amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function batchTransferTokenERC1155(\n address asset,\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory amounts,\n bytes memory data\n ) external {\n IERC1155Upgradeable(asset).safeBatchTransferFrom(from, to, ids, amounts, data);\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_RECEIVED;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure returns (bytes4) {\n return ERC1155_BATCH_RECEIVED;\n }\n\n function supportsInterface(bytes4 _interfaceId) public view override returns (bool interfaceId) {\n interfaceId = super.supportsInterface(_interfaceId);\n return interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\n// solhint-disable code-complexity\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"operator-filter-registry/src/IOperatorFilterRegistry.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n OperatorFilterRegistryErrorsAndEvents\n} from \"operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol\";\n\n/**\n * @title MockOperatorFilterRegistry\n * @notice Made based on the OperatorFilterRegistry of openSea at https://github.com/ProjectOpenSea/operator-filter-registry/blob/main/src/OperatorFilterRegistry.sol\n * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be\n * * restricted according to the isOperatorAllowed function.\n */\ncontract MockOperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents {\n using EnumerableSet for EnumerableSet.AddressSet;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052)\n /// Note that this will also be a smart contract's codehash when making calls from its constructor.\n bytes32 internal constant EOA_CODEHASH = keccak256(\"\");\n\n mapping(address => EnumerableSet.AddressSet) private _filteredOperators;\n mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes;\n mapping(address => address) private _registrations;\n mapping(address => EnumerableSet.AddressSet) private _subscribers;\n\n constructor(address _defaultSubscription, address[] memory _blacklistedAddresses) {\n _registrations[_defaultSubscription] = _defaultSubscription;\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[_defaultSubscription];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[_defaultSubscription];\n for (uint256 i; i < _blacklistedAddresses.length; i++) {\n filteredOperatorsRef.add(_blacklistedAddresses[i]);\n bytes32 codeHash = _blacklistedAddresses[i].codehash;\n filteredCodeHashesRef.add(codeHash);\n }\n }\n\n /**\n * @notice Restricts method caller to the address or EIP-173 \"owner()\"\n */\n modifier onlyAddressOrOwner(address addr) {\n if (msg.sender != addr) {\n try Ownable(addr).owner() returns (address owner) {\n if (msg.sender != owner) {\n revert OnlyAddressOrOwner();\n }\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NotOwnable();\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n }\n _;\n }\n\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n * Note that this method will *revert* if an operator or its codehash is filtered with an error that is\n * more informational than a false boolean, so smart contracts that query this method for informational\n * purposes will need to wrap in a try/catch or perform a low-level staticcall in order to handle the case\n * that an operator is filtered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n EnumerableSet.AddressSet storage filteredOperatorsRef;\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef;\n\n filteredOperatorsRef = _filteredOperators[registration];\n filteredCodeHashesRef = _filteredCodeHashes[registration];\n\n if (filteredOperatorsRef.contains(operator)) {\n revert AddressFiltered(operator);\n }\n if (operator.code.length > 0) {\n bytes32 codeHash = operator.codehash;\n if (filteredCodeHashesRef.contains(codeHash)) {\n revert CodeHashFiltered(operator, codeHash);\n }\n }\n }\n return true;\n }\n\n //////////////////\n // AUTH METHODS //\n //////////////////\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external onlyAddressOrOwner(registrant) {\n if (_registrations[registrant] != address(0)) {\n revert AlreadyRegistered();\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n }\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address registrant) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = address(0);\n emit RegistrationUpdated(registrant, false);\n }\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n if (registrant == subscription) {\n revert CannotSubscribeToSelf();\n }\n address subscriptionRegistration = _registrations[subscription];\n if (subscriptionRegistration == address(0)) {\n revert NotRegistered(subscription);\n }\n if (subscriptionRegistration != subscription) {\n revert CannotSubscribeToRegistrantWithSubscription(subscription);\n }\n\n _registrations[registrant] = subscription;\n _subscribers[subscription].add(registrant);\n emit RegistrationUpdated(registrant, true);\n emit SubscriptionUpdated(registrant, subscription, true);\n }\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy)\n external\n onlyAddressOrOwner(registrant)\n {\n if (registrantToCopy == registrant) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration != address(0)) {\n revert AlreadyRegistered();\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _registrations[registrant] = registrant;\n emit RegistrationUpdated(registrant, true);\n _copyEntries(registrant, registrantToCopy);\n }\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n\n if (!filtered) {\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n } else {\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n }\n emit OperatorUpdated(registrant, operator, filtered);\n }\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codeHash,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n\n if (!filtered) {\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n } else {\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n }\n emit CodeHashUpdated(registrant, codeHash, filtered);\n }\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant];\n uint256 operatorsLength = operators.length;\n if (!filtered) {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool removed = filteredOperatorsRef.remove(operator);\n if (!removed) {\n revert AddressNotFiltered(operator);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < operatorsLength; ) {\n address operator = operators[i];\n bool added = filteredOperatorsRef.add(operator);\n if (!added) {\n revert AddressAlreadyFiltered(operator);\n }\n unchecked {++i;}\n }\n }\n emit OperatorsUpdated(registrant, operators, filtered);\n }\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n * Note that this will allow adding the bytes32(0) codehash, which could result in unexpected behavior,\n * since calling `isCodeHashFiltered` will return true for bytes32(0), which is the codeHash of any\n * un-initialized account. Since un-initialized accounts have no code, the registry will not validate\n * that an un-initalized account's codeHash is not filtered. By the time an account is able to\n * act as an operator (an account is initialized or a smart contract exclusively in the context of its\n * constructor), it will have a codeHash of EOA_CODEHASH, which cannot be filtered.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant];\n uint256 codeHashesLength = codeHashes.length;\n if (!filtered) {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n bool removed = filteredCodeHashesRef.remove(codeHash);\n if (!removed) {\n revert CodeHashNotFiltered(codeHash);\n }\n unchecked {++i;}\n }\n } else {\n for (uint256 i = 0; i < codeHashesLength; ) {\n bytes32 codeHash = codeHashes[i];\n if (codeHash == EOA_CODEHASH) {\n revert CannotFilterEOAs();\n }\n bool added = filteredCodeHashesRef.add(codeHash);\n if (!added) {\n revert CodeHashAlreadyFiltered(codeHash);\n }\n unchecked {++i;}\n }\n }\n emit CodeHashesUpdated(registrant, codeHashes, filtered);\n }\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) {\n if (registrant == newSubscription) {\n revert CannotSubscribeToSelf();\n }\n if (newSubscription == address(0)) {\n revert CannotSubscribeToZeroAddress();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == newSubscription) {\n revert AlreadySubscribed(newSubscription);\n }\n address newSubscriptionRegistration = _registrations[newSubscription];\n if (newSubscriptionRegistration == address(0)) {\n revert NotRegistered(newSubscription);\n }\n if (newSubscriptionRegistration != newSubscription) {\n revert CannotSubscribeToRegistrantWithSubscription(newSubscription);\n }\n\n if (registration != registrant) {\n _subscribers[registration].remove(registrant);\n emit SubscriptionUpdated(registrant, registration, false);\n }\n _registrations[registrant] = newSubscription;\n _subscribers[newSubscription].add(registrant);\n emit SubscriptionUpdated(registrant, newSubscription, true);\n }\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) {\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration == registrant) {\n revert NotSubscribed();\n }\n _subscribers[registration].remove(registrant);\n _registrations[registrant] = registrant;\n emit SubscriptionUpdated(registrant, registration, false);\n if (copyExistingEntries) {\n _copyEntries(registrant, registration);\n }\n }\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) {\n if (registrant == registrantToCopy) {\n revert CannotCopyFromSelf();\n }\n address registration = _registrations[registrant];\n if (registration == address(0)) {\n revert NotRegistered(registrant);\n }\n if (registration != registrant) {\n revert CannotUpdateWhileSubscribed(registration);\n }\n address registrantRegistration = _registrations[registrantToCopy];\n if (registrantRegistration == address(0)) {\n revert NotRegistered(registrantToCopy);\n }\n _copyEntries(registrant, registrantToCopy);\n }\n\n /// @dev helper to copy entries from registrantToCopy to registrant and emit events\n function _copyEntries(address registrant, address registrantToCopy) private {\n EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy];\n EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy];\n uint256 filteredOperatorsLength = filteredOperatorsRef.length();\n uint256 filteredCodeHashesLength = filteredCodeHashesRef.length();\n for (uint256 i = 0; i < filteredOperatorsLength; ) {\n address operator = filteredOperatorsRef.at(i);\n bool added = _filteredOperators[registrant].add(operator);\n if (added) {\n emit OperatorUpdated(registrant, operator, true);\n }\n unchecked {++i;}\n }\n for (uint256 i = 0; i < filteredCodeHashesLength; ) {\n bytes32 codehash = filteredCodeHashesRef.at(i);\n bool added = _filteredCodeHashes[registrant].add(codehash);\n if (added) {\n emit CodeHashUpdated(registrant, codehash, true);\n }\n unchecked {++i;}\n }\n }\n\n //////////////////\n // VIEW METHODS //\n //////////////////\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address registrant) external view returns (address subscription) {\n subscription = _registrations[registrant];\n if (subscription == address(0)) {\n revert NotRegistered(registrant);\n } else if (subscription == registrant) {\n subscription = address(0);\n }\n }\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external view returns (address[] memory) {\n return _subscribers[registrant].values();\n }\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external view returns (address) {\n return _subscribers[registrant].at(index);\n }\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].contains(operator);\n }\n return _filteredOperators[registrant].contains(operator);\n }\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) {\n bytes32 codeHash = operatorWithCode.codehash;\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].contains(codeHash);\n }\n return _filteredCodeHashes[registrant].contains(codeHash);\n }\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address registrant) external view returns (bool) {\n return _registrations[registrant] != address(0);\n }\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address registrant) external view returns (address[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].values();\n }\n return _filteredOperators[registrant].values();\n }\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].values();\n }\n return _filteredCodeHashes[registrant].values();\n }\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external view returns (address) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredOperators[registration].at(index);\n }\n return _filteredOperators[registrant].at(index);\n }\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) {\n address registration = _registrations[registrant];\n if (registration != registrant) {\n return _filteredCodeHashes[registration].at(index);\n }\n return _filteredCodeHashes[registrant].at(index);\n }\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address a) external view returns (bytes32) {\n return a.codehash;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/mock/MockOperatorFilterSubscription.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IOperatorFilterRegistry} from \"operator-filter-registry/src/IOperatorFilterRegistry.sol\";\nimport {Ownable2Step} from \"@openzeppelin/contracts/access/Ownable2Step.sol\";\n\n/**\n * @title OwnedRegistrant\n * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries,\n * to facilitate a subscription whose ownership can be transferred.\n */\n\ncontract MockOperatorFilterSubscription is Ownable2Step {\n address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);\n\n /// @dev The constructor that is called when the contract is being deployed.\n /// @dev This contract is based on OpenSea's OwnedRegistrant.\n /// @dev The param _localRegistry has been added to the constructor to enable local testing.\n constructor(address _owner, address _localRegistry) {\n IOperatorFilterRegistry(_localRegistry).registerAndCopyEntries(address(this), DEFAULT_SUBSCRIPTION);\n transferOwnership(_owner);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IERC20Approve.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\ninterface IERC20Approve {\n function approve(address spender, uint256 amount) external returns (bool);\n\n function increaseAllowance(address spender, uint256 amount) external returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IMultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\n/**\n * Multi-receiver EIP2981 reference override implementation\n */\ninterface IMultiRoyaltyDistributor is IERC165 {\n event TokenRoyaltyRemoved(uint256 tokenId);\n event TokenRoyaltySet(uint256 tokenId, uint16 royaltyBPS, address recipient);\n event DefaultRoyaltyBpsSet(uint16 royaltyBPS);\n\n event DefaultRoyaltyReceiverSet(address recipient);\n\n event RoyaltyRecipientSet(address splitter, address recipient);\n\n struct TokenRoyaltyConfig {\n uint256 tokenId;\n uint16 royaltyBPS;\n Recipient[] recipients;\n }\n\n /**\n * @dev Set per token royalties. Passing a recipient of address(0) will delete any existing configuration\n */\n function setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) external;\n\n /**\n * @dev Get all token royalty configurations\n */\n function getTokenRoyalties() external view returns (TokenRoyaltyConfig[] memory);\n\n /**\n * @dev Get the default royalty\n */\n function getDefaultRoyalty() external view returns (uint16 bps, Recipient[] memory);\n\n /**\n * @dev Set a default royalty e. Will be used if no token specific configuration is set\n */\n function setDefaultRoyaltyBps(uint16 bps) external;\n\n function setDefaultRoyaltyReceiver(address payable defaultReceiver) external;\n\n /**\n * @dev Helper function to get all splits contracts\n */\n function getAllSplits() external view returns (address payable[] memory);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/FallbackRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {FallbackRegistry} from \"@manifoldxyz/royalty-registry-solidity/contracts/FallbackRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/MockMarketplace.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981} from \"@openzeppelin/contracts/interfaces/IERC2981.sol\";\nimport {IERC1155} from \"@openzeppelin/contracts/interfaces/IERC1155.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/interfaces/IERC721.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/interfaces/IERC20.sol\";\nimport {IRoyaltyEngineV1} from \"@manifoldxyz/royalty-registry-solidity/contracts/IRoyaltyEngineV1.sol\";\n\ncontract MockMarketplace {\n IRoyaltyEngineV1 public royaltyEngine;\n\n constructor(address _royaltyEngine) {\n royaltyEngine = IRoyaltyEngineV1(_royaltyEngine);\n }\n\n function distributeRoyaltyEIP2981(\n uint256 erc20TokenAmount,\n IERC20 erc20Contract,\n address nftContract,\n uint256 nftId,\n address nftBuyer,\n address nftSeller,\n bool is1155\n ) external payable {\n if (msg.value == 0) {\n require(erc20TokenAmount > 0, \"erc20 token ammount can't be zero\");\n (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, erc20TokenAmount);\n erc20Contract.transferFrom(nftBuyer, royaltyReceiver, value);\n erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - value));\n } else {\n (address royaltyReceiver, uint256 value) = IERC2981(nftContract).royaltyInfo(nftId, msg.value);\n (bool sent, ) = royaltyReceiver.call{value: value}(\"\");\n require(sent, \"Failed to send distributeRoyaltyEIP2981Ether\");\n (bool sentToSeller, ) = nftSeller.call{value: msg.value - value}(\"\");\n require(sentToSeller, \"Failed to send to seller\");\n }\n if (is1155) {\n IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, \"0x\");\n } else {\n IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, \"0x\");\n }\n }\n\n function distributeRoyaltyRoyaltyEngine(\n uint256 erc20TokenAmount,\n IERC20 erc20Contract,\n address nftContract,\n uint256 nftId,\n address nftBuyer,\n address nftSeller,\n bool is1155\n ) external payable {\n if (msg.value == 0) {\n require(erc20TokenAmount > 0, \"erc20 token ammount can't be zero\");\n uint256 TotalRoyalty;\n (address payable[] memory recipients, uint256[] memory amounts) =\n royaltyEngine.getRoyalty(address(nftContract), nftId, erc20TokenAmount);\n for (uint256 i; i < recipients.length; i++) {\n erc20Contract.transferFrom(nftBuyer, recipients[i], amounts[i]);\n TotalRoyalty += amounts[i];\n }\n erc20Contract.transferFrom(nftBuyer, nftSeller, (erc20TokenAmount - TotalRoyalty));\n } else {\n (address payable[] memory recipients, uint256[] memory amounts) =\n royaltyEngine.getRoyalty(address(nftContract), nftId, msg.value);\n uint256 TotalRoyalty;\n for (uint256 i; i < recipients.length; i++) {\n (bool sent, ) = recipients[i].call{value: amounts[i]}(\"\");\n require(sent, \"Failed to send Ether\");\n TotalRoyalty += amounts[i];\n }\n (bool sentToSeller, ) = nftSeller.call{value: msg.value - TotalRoyalty}(\"\");\n require(sentToSeller, \"Failed to send to seller\");\n }\n if (is1155) {\n IERC1155(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, 1, \"0x\");\n } else {\n IERC721(nftContract).safeTransferFrom(nftSeller, nftBuyer, nftId, \"0x\");\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyEngineV1.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyEngineV1} from \"@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyEngineV1.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/RoyaltyRegistry.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\nimport {RoyaltyRegistry} from \"@manifoldxyz/royalty-registry-solidity/contracts/RoyaltyRegistry.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/mock/TestERC20.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n/* solhint-disable-next-line no-empty-blocks*/\n\npragma solidity ^0.8.0;\n\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestERC20 is ERC20 {\n /* solhint-disable-next-line no-empty-blocks*/\n constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/MultiRoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\nimport {\n IEIP2981MultiReceiverRoyaltyOverride\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IMultiReceiverRoyaltyOverride.sol\";\nimport {IMultiRoyaltyDistributor} from \"./interfaces/IMultiRoyaltyDistributor.sol\";\nimport {\n IRoyaltySplitter,\n IERC165\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IEIP2981} from \"@manifoldxyz/royalty-registry-solidity/contracts/specs/IEIP2981.sol\";\nimport {IRoyaltyManager, Recipient} from \"./interfaces/IRoyaltyManager.sol\";\n\n/// @title MultiRoyaltyDistributer\n/// @author The Sandbox\n/// @dev The MultiRoyaltyDistributer contract implements the ERC-2981 and ERC-165 interfaces for a royalty payment system. This payment system can be used to pay royalties to multiple recipients through splitters.\n/// @dev This contract calls to the Royalties manager contract to deploy RoyaltySplitter for a creator to slip its royalty between the creator and Sandbox and use it for every token minted by that creator.\nabstract contract MultiRoyaltyDistributor is IEIP2981, IMultiRoyaltyDistributor, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public _defaultRoyaltyBPS;\n address payable public _defaultRoyaltyReceiver;\n address public royaltyManager;\n\n mapping(uint256 => address payable) public _tokenRoyaltiesSplitter;\n uint256[] private _tokensWithRoyalties;\n\n function __MultiRoyaltyDistributor_init(\n address payable defaultRecipient,\n uint16 defaultBps,\n address _royaltyManager\n ) internal {\n _defaultRoyaltyReceiver = defaultRecipient;\n _defaultRoyaltyBPS = defaultBps;\n royaltyManager = _royaltyManager;\n }\n\n /// @notice EIP 165 interface function\n /// @dev used to check the interface implemented\n /// @param interfaceId to be checked for implementation\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165)\n returns (bool)\n {\n return\n interfaceId == type(IEIP2981).interfaceId ||\n interfaceId == type(IEIP2981MultiReceiverRoyaltyOverride).interfaceId ||\n interfaceId == type(IMultiRoyaltyDistributor).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /// @notice sets token royalty\n /// @dev deploys a splitter if a creator doesn't have one\n /// @param tokenId id of token\n /// @param royaltyBPS the bps of for EIP2981 royalty\n /// @param creator of the token\n function _setTokenRoyalties(\n uint256 tokenId,\n uint16 royaltyBPS,\n address payable recipient,\n address creator\n ) internal {\n require(royaltyBPS < TOTAL_BASIS_POINTS, \"Invalid bps\");\n address payable creatorSplitterAddress = IRoyaltyManager(royaltyManager).deploySplitter(creator, recipient);\n _tokenRoyaltiesSplitter[tokenId] = creatorSplitterAddress;\n _tokensWithRoyalties.push(tokenId);\n emit TokenRoyaltySet(tokenId, royaltyBPS, recipient);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty\n /// @param bps the new default royalty in BPS to be set\n function _setDefaultRoyaltyBps(uint16 bps) internal {\n require(bps < TOTAL_BASIS_POINTS, \"Invalid bps\");\n _defaultRoyaltyBPS = bps;\n emit DefaultRoyaltyBpsSet(bps);\n }\n\n /// @dev Internal function to set the default EIP2981 royalty receiver\n /// @param defaultReceiver is the new default royalty receiver in BPS to be set\n function _setDefaultRoyaltyReceiver(address payable defaultReceiver) internal {\n require(defaultReceiver != address(0), \"Default receiver can't be zero\");\n _defaultRoyaltyReceiver = defaultReceiver;\n emit DefaultRoyaltyReceiverSet(defaultReceiver);\n }\n\n /// @notice Returns royalty receivers and their split of royalty for each token\n /// @return royaltyConfigs receivers and their split array as long as the number of tokens.\n function getTokenRoyalties() external view override returns (TokenRoyaltyConfig[] memory royaltyConfigs) {\n royaltyConfigs = new TokenRoyaltyConfig[](_tokensWithRoyalties.length);\n for (uint256 i; i < _tokensWithRoyalties.length; ++i) {\n TokenRoyaltyConfig memory royaltyConfig;\n uint256 tokenId = _tokensWithRoyalties[i];\n address splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n royaltyConfig.recipients = IRoyaltySplitter(splitterAddress).getRecipients();\n }\n royaltyConfig.tokenId = tokenId;\n royaltyConfigs[i] = royaltyConfig;\n }\n }\n\n /// @notice Returns default royalty bps and the default recipient following EIP2981\n /// @dev In this contract there is only one default recipient so its split is 100 percent or 10000 points.\n /// @return bps the royalty percentage in BPS\n /// @return recipients The default recipients with their share of the royalty\n function getDefaultRoyalty() external view override returns (uint16 bps, Recipient[] memory recipients) {\n recipients[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return (_defaultRoyaltyBPS, recipients);\n }\n\n /// @notice EIP 2981 royalty info function to return the royalty receiver and royalty amount\n /// @param tokenId of the token for which the royalty is needed to be distributed\n /// @param value the amount on which the royalty is calculated\n /// @return address the royalty receiver\n /// @return value the EIP2981 royalty\n function royaltyInfo(uint256 tokenId, uint256 value) public view override returns (address, uint256) {\n if (_tokenRoyaltiesSplitter[tokenId] != address(0)) {\n return (_tokenRoyaltiesSplitter[tokenId], (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n if (_defaultRoyaltyReceiver != address(0) && _defaultRoyaltyBPS != 0) {\n return (_defaultRoyaltyReceiver, (value * _defaultRoyaltyBPS) / TOTAL_BASIS_POINTS);\n }\n return (address(0), 0);\n }\n\n /// @notice returns the EIP-2981 royalty receiver for each token (i.e. splitters) including the default royalty receiver.\n /// @return splits the royalty receiver's array\n function getAllSplits() external view override returns (address payable[] memory splits) {\n uint256 startingIndex;\n uint256 endingIndex = _tokensWithRoyalties.length;\n if (_defaultRoyaltyReceiver != address(0)) {\n splits = new address payable[](1 + _tokensWithRoyalties.length);\n splits[0] = _defaultRoyaltyReceiver;\n startingIndex = 1;\n ++endingIndex;\n } else {\n // unreachable in practice\n splits = new address payable[](_tokensWithRoyalties.length);\n }\n for (uint256 i = startingIndex; i < endingIndex; ++i) {\n splits[i] = _tokenRoyaltiesSplitter[_tokensWithRoyalties[i - startingIndex]];\n }\n }\n\n /// @notice returns the royalty recipients for each tokenId.\n /// @dev returns the default address for tokens with no recipients.\n /// @param tokenId is the token id for which the recipient should be returned.\n /// @return addresses of royalty recipient of the token.\n function getRecipients(uint256 tokenId) public view returns (Recipient[] memory) {\n address payable splitterAddress = _tokenRoyaltiesSplitter[tokenId];\n if (splitterAddress != address(0)) {\n return IRoyaltySplitter(splitterAddress).getRecipients();\n }\n Recipient[] memory defaultRecipient = new Recipient[](1);\n defaultRecipient[0] = Recipient({recipient: _defaultRoyaltyReceiver, bps: TOTAL_BASIS_POINTS});\n return defaultRecipient;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {AccessControlUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n IRoyaltySplitter,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {RoyaltySplitter} from \"./RoyaltySplitter.sol\";\nimport {Clones} from \"@openzeppelin/contracts/proxy/Clones.sol\";\n\n/// @title RoyaltyManager\n/// @author The Sandbox\n/// @notice Registry contract to set the common Recipient and Split for the RoyaltySplitter. Also, to set the royalty info\n/// for contracts that don't use the RoyaltySplitter.\ncontract RoyaltyManager is AccessControlUpgradeable, IRoyaltyManager {\n bytes32 public constant CONTRACT_ROYALTY_SETTER_ROLE = keccak256(\"CONTRACT_ROYALTY_SETTER\");\n\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n uint16 public commonSplit;\n address payable public commonRecipient;\n mapping(address => uint16) public contractRoyalty;\n mapping(address => address payable) public _creatorRoyaltiesSplitter;\n address internal _royaltySplitterCloneable;\n\n /// @notice initialization function for the deployment of contract\n /// @dev called during the deployment via the proxy.\n /// @param _commonRecipient the != address(0)common recipient for all the splitters\n /// @param _commonSplit split for the common recipient's and creator split would be 10000 - commonSplit\n /// @param royaltySplitterCloneable address of cloneable splitter contract for royalties distribution\n /// @param managerAdmin address of RoyaltyManager contract.\n /// @param contractRoyaltySetter the address of royalty setter of contract.\n function initialize(\n address payable _commonRecipient,\n uint16 _commonSplit,\n address royaltySplitterCloneable,\n address managerAdmin,\n address contractRoyaltySetter\n ) external initializer {\n _setRecipient(_commonRecipient);\n _setSplit(_commonSplit);\n _grantRole(DEFAULT_ADMIN_ROLE, managerAdmin);\n _grantRole(CONTRACT_ROYALTY_SETTER_ROLE, contractRoyaltySetter);\n _royaltySplitterCloneable = royaltySplitterCloneable;\n }\n\n /// @notice sets royalty recipient wallet\n /// @dev should be called by the creator. The bps is not set on the splitter as it is set here on manager contract.\n /// @param recipient new recipient wallet.\n function setRoyaltyRecipient(address payable recipient) external {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[msg.sender];\n require(creatorSplitterAddress != address(0), \"Manager: No splitter deployed for the creator\");\n address _recipient = RoyaltySplitter(creatorSplitterAddress)._recipient();\n require(_recipient != recipient, \"Recipient already set\");\n Recipient[] memory newRecipient = new Recipient[](1);\n newRecipient[0] = Recipient({recipient: recipient, bps: 0});\n RoyaltySplitter(creatorSplitterAddress).setRecipients(newRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonRecipient is the common recipient for all the splitters\n function setRecipient(address payable _commonRecipient) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setRecipient(_commonRecipient);\n }\n\n /// @notice sets the common recipient and common split\n /// @dev can only be called by the admin.\n /// @param _commonSplit split for the common recipient and creators split would be 10000 - commonSplit\n function setSplit(uint16 _commonSplit) external override onlyRole(DEFAULT_ADMIN_ROLE) {\n _setSplit(_commonSplit);\n }\n\n function _setRecipient(address payable _commonRecipient) internal {\n require(_commonRecipient != address(0), \"Manager: Can't set common recipient to zero address\");\n commonRecipient = _commonRecipient;\n emit RecipientSet(_commonRecipient);\n }\n\n function _setSplit(uint16 _commonSplit) internal {\n require(_commonSplit < TOTAL_BASIS_POINTS, \"Manager: Can't set common recipient to zero address\");\n commonSplit = _commonSplit;\n emit SplitSet(_commonSplit);\n }\n\n /// @notice called to set the EIP 2981 royalty split\n /// @dev can only be called by contract royalty setter.\n /// @param _royaltyBps the royalty split for the EIP 2981\n function setContractRoyalty(address contractAddress, uint16 _royaltyBps)\n external\n onlyRole(CONTRACT_ROYALTY_SETTER_ROLE)\n {\n require(_royaltyBps < TOTAL_BASIS_POINTS, \"Manager: Royalty can't be greater than Total base points\");\n contractRoyalty[contractAddress] = _royaltyBps;\n emit RoyaltySet(_royaltyBps, contractAddress);\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return recipient which has the common recipient and split\n function getCommonRecipient() external view override returns (Recipient memory recipient) {\n recipient = Recipient({recipient: commonRecipient, bps: commonSplit});\n return recipient;\n }\n\n /// @notice deploys splitter for creator\n /// @dev should only called once per creator\n /// @param creator the address of the creator\n /// @param recipient the wallet of the recipient where they would receive their royalty\n /// @return creatorSplitterAddress deployed for a creator\n function deploySplitter(address creator, address payable recipient) external returns (address payable) {\n address payable creatorSplitterAddress = _creatorRoyaltiesSplitter[creator];\n if (creatorSplitterAddress == address(0)) {\n creatorSplitterAddress = payable(Clones.clone(_royaltySplitterCloneable));\n RoyaltySplitter(creatorSplitterAddress).initialize(recipient, address(this));\n _creatorRoyaltiesSplitter[creator] = creatorSplitterAddress;\n }\n return creatorSplitterAddress;\n }\n\n /// @notice returns the address of splitter of a creator.\n /// @param creator the address of the creator\n /// @return creatorSplitterAddress deployed for a creator\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable) {\n return _creatorRoyaltiesSplitter[creator];\n }\n\n /// @notice to be called by the splitters to get the common recipient and split\n /// @return creatorSplit which is 10000 - commonSplit\n function getCreatorSplit() external view returns (uint16) {\n return TOTAL_BASIS_POINTS - commonSplit;\n }\n\n /// @notice returns the commonRecipient and EIP2981 royalty split\n /// @return commonRecipient\n /// @return royaltySplit\n function getRoyaltyInfo() external view returns (address, uint16) {\n return (commonRecipient, contractRoyalty[msg.sender]);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {OwnableUpgradeable} from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport {AddressUpgradeable} from \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\nimport {SafeMath} from \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {BytesLibrary} from \"@manifoldxyz/royalty-registry-solidity/contracts/libraries/BytesLibrary.sol\";\nimport {\n IRoyaltySplitter,\n IERC165,\n Recipient\n} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {IERC20Approve} from \"./interfaces/IERC20Approve.sol\";\n\n/// @title RoyaltySplitter\n/// @author The Sandbox\n/// @notice RoyaltySplitter contract is deployed by the RoyaltyManager contract for a creator to get his royalty's share.\ncontract RoyaltySplitter is Initializable, OwnableUpgradeable, IRoyaltySplitter, ERC165Upgradeable {\n using BytesLibrary for bytes;\n using AddressUpgradeable for address payable;\n using AddressUpgradeable for address;\n using SafeMath for uint256;\n\n uint256 internal constant TOTAL_BASIS_POINTS = 10000;\n uint256 internal constant IERC20_APPROVE_SELECTOR =\n 0x095ea7b300000000000000000000000000000000000000000000000000000000;\n uint256 internal constant SELECTOR_MASK = 0xffffffff00000000000000000000000000000000000000000000000000000000;\n\n address payable public _recipient;\n IRoyaltyManager public _royaltyManager;\n\n event ETHTransferred(address indexed account, uint256 amount);\n event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165, ERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IRoyaltySplitter).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @notice initialize the contract\n /// @dev can only be run once.\n /// @param recipient the wallet of the creator when the contract is deployed\n /// @param royaltyManager the address of the royalty manager contract.\n function initialize(address payable recipient, address royaltyManager) public initializer {\n __Ownable_init();\n _royaltyManager = IRoyaltyManager(royaltyManager);\n _recipient = recipient;\n }\n\n /// @notice sets recipient for the splitter\n /// @dev only the owner can call this.\n /// @param recipients the array of recipients which should only have one recipient.\n function setRecipients(Recipient[] calldata recipients) external override onlyOwner {\n _setRecipients(recipients);\n }\n\n function _setRecipients(Recipient[] calldata recipients) private {\n delete _recipient;\n require(recipients.length == 1, \"Invalid recipents length\");\n _recipient = recipients[0].recipient;\n }\n\n /// @notice to get recipients of royalty through this splitter and their splits of royalty.\n /// @return recipients of royalty through this splitter and their splits of royalty.\n function getRecipients() external view override returns (Recipient[] memory) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory recipients = new Recipient[](2);\n recipients[0].recipient = _recipient;\n recipients[0].bps = creatorSplit;\n recipients[1] = commonRecipient;\n return recipients;\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev splits ETH every time it is sent to this contract as royalty.\n receive() external payable {\n _splitETH(msg.value);\n }\n\n /// @notice Splits and forwards ETH to the royalty receivers\n /// @dev normally ETH should be split automatically by receive function.\n function splitETH() public {\n _splitETH(address(this).balance);\n }\n\n function _splitETH(uint256 value) internal {\n if (value > 0) {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 totalSent;\n uint256 amountToSend;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n amountToSend = (value * recipient.bps) / TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n recipient.recipient.sendValue(amountToSend);\n emit ETHTransferred(recipient.recipient, amountToSend);\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = value - totalSent;\n }\n _recipients[0].recipient.sendValue(amountToSend);\n emit ETHTransferred(_recipients[0].recipient, amountToSend);\n }\n }\n\n /// @notice split ERC20 Tokens owned by this contract.\n /// @dev can only be called by one of the recipients\n /// @param erc20Contract the address of the tokens to be split.\n function splitERC20Tokens(IERC20 erc20Contract) public {\n require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n }\n\n function _splitERC20Tokens(IERC20 erc20Contract) internal returns (bool) {\n try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n if (balance == 0) {\n return false;\n }\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n uint16 creatorSplit = _royaltyManager.getCreatorSplit();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n Recipient[] memory _recipients = new Recipient[](2);\n _recipients[0].recipient = _recipient;\n _recipients[0].bps = creatorSplit;\n _recipients[1] = commonRecipient;\n uint256 amountToSend;\n uint256 totalSent;\n unchecked {\n for (uint256 i = _recipients.length - 1; i > 0; i--) {\n Recipient memory recipient = _recipients[i];\n bool success;\n (success, amountToSend) = balance.tryMul(recipient.bps);\n\n amountToSend /= TOTAL_BASIS_POINTS;\n totalSent += amountToSend;\n try erc20Contract.transfer(recipient.recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), recipient.recipient, amountToSend);\n } catch {\n return false;\n }\n }\n // Favor the 1st recipient if there are any rounding issues\n amountToSend = balance - totalSent;\n }\n try erc20Contract.transfer(_recipients[0].recipient, amountToSend) {\n emit ERC20Transferred(address(erc20Contract), _recipients[0].recipient, amountToSend);\n } catch {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /// @notice made for unexpected scenarios when assets are sent to this contact such that they could be recovered.\n /// @dev first attempts to split ERC20 tokens.\n /// @param target target of the call\n /// @param callData for the call.\n function proxyCall(address payable target, bytes calldata callData) external {\n Recipient memory commonRecipient = _royaltyManager.getCommonRecipient();\n require(\n commonRecipient.recipient == msg.sender || _recipient == msg.sender,\n \"Split: Can only be called by one of the recipients\"\n );\n require(\n !callData.startsWith(IERC20Approve.approve.selector) &&\n !callData.startsWith(IERC20Approve.increaseAllowance.selector),\n \"Split: ERC20 tokens must be split\"\n );\n /* solhint-disable-next-line no-empty-blocks*/\n try this.splitERC20Tokens(IERC20(target)) {} catch {}\n target.functionCall(callData);\n }\n}\n" + }, + "operator-filter-registry/src/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(address registrant, address operator, bool filtered) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(address registrant, address[] calldata operators, bool filtered) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "operator-filter-registry/src/OperatorFilterRegistryErrorsAndEvents.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ncontract OperatorFilterRegistryErrorsAndEvents {\n /// @notice Emitted when trying to register an address that has no code.\n error CannotFilterEOAs();\n\n /// @notice Emitted when trying to add an address that is already filtered.\n error AddressAlreadyFiltered(address operator);\n\n /// @notice Emitted when trying to remove an address that is not filtered.\n error AddressNotFiltered(address operator);\n\n /// @notice Emitted when trying to add a codehash that is already filtered.\n error CodeHashAlreadyFiltered(bytes32 codeHash);\n\n /// @notice Emitted when trying to remove a codehash that is not filtered.\n error CodeHashNotFiltered(bytes32 codeHash);\n\n /// @notice Emitted when the caller is not the address or EIP-173 \"owner()\"\n error OnlyAddressOrOwner();\n\n /// @notice Emitted when the registrant is not registered.\n error NotRegistered(address registrant);\n\n /// @notice Emitted when the registrant is already registered.\n error AlreadyRegistered();\n\n /// @notice Emitted when the registrant is already subscribed.\n error AlreadySubscribed(address subscription);\n\n /// @notice Emitted when the registrant is not subscribed.\n error NotSubscribed();\n\n /// @notice Emitted when trying to update a registration where the registrant is already subscribed.\n error CannotUpdateWhileSubscribed(address subscription);\n\n /// @notice Emitted when trying to subscribe to itself.\n error CannotSubscribeToSelf();\n\n /// @notice Emitted when trying to subscribe to the zero address.\n error CannotSubscribeToZeroAddress();\n\n /// @notice Emitted when trying to register and the contract is not ownable (EIP-173 \"owner()\")\n error NotOwnable();\n\n /// @notice Emitted when an address is filtered.\n error AddressFiltered(address filtered);\n\n /// @notice Emitted when a codeHash is filtered.\n error CodeHashFiltered(address account, bytes32 codeHash);\n\n /// @notice Emited when trying to register to a registrant with a subscription.\n error CannotSubscribeToRegistrantWithSubscription(address registrant);\n\n /// @notice Emitted when trying to copy a registration from itself.\n error CannotCopyFromSelf();\n\n /// @notice Emitted when a registration is updated.\n event RegistrationUpdated(address indexed registrant, bool indexed registered);\n\n /// @notice Emitted when an operator is updated.\n event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered);\n\n /// @notice Emitted when multiple operators are updated.\n event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered);\n\n /// @notice Emitted when a codeHash is updated.\n event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered);\n\n /// @notice Emitted when multiple codeHashes are updated.\n event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered);\n\n /// @notice Emitted when a subscription is updated.\n event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed);\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/f945dbcb44c3ca52caf6c6145c517ab2.json b/packages/deploy/deployments/mumbai/solcInputs/f945dbcb44c3ca52caf6c6145c517ab2.json new file mode 100644 index 0000000000..bb9206a321 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/f945dbcb44c3ca52caf6c6145c517ab2.json @@ -0,0 +1,128 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@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" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {\n ERC2771HandlerUpgradeable,\n ERC2771HandlerAbstract\n} from \"@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771HandlerUpgradeable,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public highestTierIndex;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_init(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n highestTierIndex = i;\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= highestTierIndex, \"Catalyst: invalid catalyst id\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n uint256 newCatId = ++highestTierIndex;\n ERC1155URIStorageUpgradeable._setURI(newCatId, ipfsCID);\n emit NewCatalystTypeAdded(newCatId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _setTrustedForwarder(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771HandlerAbstract) returns (address) {\n return ERC2771HandlerAbstract._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData()\n internal\n view\n virtual\n override(ContextUpgradeable, ERC2771HandlerAbstract)\n returns (bytes calldata)\n {\n return ERC2771HandlerAbstract._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `interfaceId`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return super.supportsInterface(interfaceId);\n }\n\n /// @notice This function is used to register Catalyst contract on the Operator Filterer Registry of Opensea.can only be called by admin.\n /// @dev used to register contract and subscribe to the subscriptionOrRegistrantToCopy's black list.\n /// @param subscriptionOrRegistrantToCopy registration address of the list to subscribe.\n /// @param subscribe bool to signify subscription \"true\"\" or to copy the list \"false\".\n function registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n {\n require(subscriptionOrRegistrantToCopy != address(0), \"Catalyst: subscription can't be zero address\");\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n /// @notice sets filter registry address deployed in test\n /// @param registry the address of the registry\n function setOperatorRegistry(address registry) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(registry != address(0), \"Catalyst: registry can't be zero address\");\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockTrustedForwarder.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {MockTrustedForwarder} from \"@sandbox-smart-contracts/dependency-metatx/contracts/test/MockTrustedForwarder.sol\";\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerAbstract.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\nabstract contract ERC2771HandlerAbstract {\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function isTrustedForwarder(address forwarder) external view returns (bool) {\n return _isTrustedForwarder(forwarder);\n }\n\n /// @notice if the call is from the trusted forwarder the sender is extracted from calldata, msg.sender otherwise\n /// @return sender the calculated address of the sender\n function _msgSender() internal view virtual returns (address sender) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n sender = msg.sender;\n }\n }\n\n /// @notice if the call is from the trusted forwarder the sender is removed from calldata\n /// @return the calldata without the sender\n function _msgData() internal view virtual returns (bytes calldata) {\n if (_isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n /// @dev this function must be IMPLEMENTED\n function _isTrustedForwarder(address forwarder) internal view virtual returns (bool);\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/ERC2771HandlerUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {ERC2771HandlerAbstract} from \"./ERC2771HandlerAbstract.sol\";\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol\ncontract ERC2771HandlerUpgradeable is Initializable, ERC2771HandlerAbstract {\n address private _trustedForwarder;\n\n /// @notice Emitted when a `newTrustedForwarder` is set, replacing the `oldTrustedForwarder`\n /// @param oldTrustedForwarder old trusted forwarder\n /// @param newTrustedForwarder new trusted forwarder\n /// @param operator the sender of the transaction\n event TrustedForwarderSet(\n address indexed oldTrustedForwarder,\n address indexed newTrustedForwarder,\n address indexed operator\n );\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init(address forwarder) internal onlyInitializing {\n __ERC2771Handler_init_unchained(forwarder);\n }\n\n /// @notice initialize the trusted forwarder address\n /// @param forwarder trusted forwarder address or zero to disable it\n function __ERC2771Handler_init_unchained(address forwarder) internal onlyInitializing {\n _setTrustedForwarder(forwarder);\n }\n\n /// @notice return the address of the trusted forwarder\n /// @return return the address of the trusted forwarder\n function getTrustedForwarder() external view returns (address) {\n return _trustedForwarder;\n }\n\n /// @notice set the address of the trusted forwarder\n /// @param newForwarder the address of the new forwarder.\n function _setTrustedForwarder(address newForwarder) internal virtual {\n require(newForwarder != _trustedForwarder, \"ERC2771HandlerUpgradeable: forwarder already set\");\n emit TrustedForwarderSet(_trustedForwarder, newForwarder, _msgSender());\n _trustedForwarder = newForwarder;\n }\n\n /// @notice return true if the forwarder is the trusted forwarder\n /// @param forwarder trusted forwarder address to check\n /// @return true if the address is the same as the trusted forwarder\n function _isTrustedForwarder(address forwarder) internal view virtual override returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "@sandbox-smart-contracts/dependency-metatx/contracts/test/MockTrustedForwarder.sol": { + "content": "//SPDX-License-Identifier: MIT\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.2;\n\ncontract MockTrustedForwarder {\n struct ForwardRequest {\n address from;\n address to;\n uint256 value;\n uint256 gasLimit;\n bytes data;\n }\n\n function execute(ForwardRequest calldata req) public payable returns (bool, bytes memory) {\n (bool success, bytes memory returndata) = req.to.call{gas: req.gasLimit, value: req.value}(\n abi.encodePacked(req.data, req.from)\n );\n assert(gasleft() > req.gasLimit / 63);\n return (success, returndata);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n _registerAndSubscribe(subscriptionOrRegistrantToCopy, subscribe);\n }\n\n function _registerAndSubscribe(address subscriptionOrRegistrantToCopy, bool subscribe) internal {\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address payable, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n\n function getContractRoyalty(address _contractAddress) external view returns (uint16 royaltyBps);\n\n function setTrustedForwarder(address _newForwarder) external;\n\n function getTrustedForwarder() external view returns (address);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\nimport {\n ERC165Upgradeable,\n IERC165Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable, ERC165Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(ERC165Upgradeable, IERC165Upgradeable)\n returns (bool)\n {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/mumbai/solcInputs/ff197be05fa71f1a9e1895e200b26c8c.json b/packages/deploy/deployments/mumbai/solcInputs/ff197be05fa71f1a9e1895e200b26c8c.json new file mode 100644 index 0000000000..05126b1d81 --- /dev/null +++ b/packages/deploy/deployments/mumbai/solcInputs/ff197be05fa71f1a9e1895e200b26c8c.json @@ -0,0 +1,119 @@ +{ + "language": "Solidity", + "sources": { + "@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/// @author: manifold.xyz\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\nstruct Recipient {\n address payable recipient;\n uint16 bps;\n}\n\ninterface IRoyaltySplitter is IERC165 {\n /**\n * @dev Set the splitter recipients. Total bps must total 10000.\n */\n function setRecipients(Recipient[] calldata recipients) external;\n\n /**\n * @dev Get the splitter recipients;\n */\n function getRecipients() external view returns (Recipient[] memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(account),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface for the NFT Royalty Standard.\n *\n * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal\n * support for royalty payments across all NFT marketplaces and ecosystem participants.\n *\n * _Available since v4.5._\n */\ninterface IERC2981Upgradeable is IERC165Upgradeable {\n /**\n * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of\n * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.\n */\n function royaltyInfo(\n uint256 tokenId,\n uint256 salePrice\n ) external view returns (address receiver, uint256 royaltyAmount);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/common/ERC2981.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IERC2981Upgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.\n *\n * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for\n * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.\n *\n * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the\n * fee is specified in basis points by default.\n *\n * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See\n * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to\n * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.\n *\n * _Available since v4.5._\n */\nabstract contract ERC2981Upgradeable is Initializable, IERC2981Upgradeable, ERC165Upgradeable {\n function __ERC2981_init() internal onlyInitializing {\n }\n\n function __ERC2981_init_unchained() internal onlyInitializing {\n }\n struct RoyaltyInfo {\n address receiver;\n uint96 royaltyFraction;\n }\n\n RoyaltyInfo private _defaultRoyaltyInfo;\n mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165Upgradeable, ERC165Upgradeable) returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @inheritdoc IERC2981Upgradeable\n */\n function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {\n RoyaltyInfo memory royalty = _tokenRoyaltyInfo[tokenId];\n\n if (royalty.receiver == address(0)) {\n royalty = _defaultRoyaltyInfo;\n }\n\n uint256 royaltyAmount = (salePrice * royalty.royaltyFraction) / _feeDenominator();\n\n return (royalty.receiver, royaltyAmount);\n }\n\n /**\n * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a\n * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an\n * override.\n */\n function _feeDenominator() internal pure virtual returns (uint96) {\n return 10000;\n }\n\n /**\n * @dev Sets the royalty information that all ids in this contract will default to.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: invalid receiver\");\n\n _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Removes default royalty information.\n */\n function _deleteDefaultRoyalty() internal virtual {\n delete _defaultRoyaltyInfo;\n }\n\n /**\n * @dev Sets the royalty information for a specific token id, overriding the global default.\n *\n * Requirements:\n *\n * - `receiver` cannot be the zero address.\n * - `feeNumerator` cannot be greater than the fee denominator.\n */\n function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {\n require(feeNumerator <= _feeDenominator(), \"ERC2981: royalty fee will exceed salePrice\");\n require(receiver != address(0), \"ERC2981: Invalid parameters\");\n\n _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);\n }\n\n /**\n * @dev Resets royalty information for the token id back to the global default.\n */\n function _resetTokenRoyalty(uint256 tokenId) internal virtual {\n delete _tokenRoyaltyInfo[tokenId];\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.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 \"./IERC1155Upgradeable.sol\";\nimport \"./IERC1155ReceiverUpgradeable.sol\";\nimport \"./extensions/IERC1155MetadataURIUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.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 ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable {\n using AddressUpgradeable 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 function __ERC1155_init(string memory uri_) internal onlyInitializing {\n __ERC1155_init_unchained(uri_);\n }\n\n function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {\n _setURI(uri_);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) {\n return\n interfaceId == type(IERC1155Upgradeable).interfaceId ||\n interfaceId == type(IERC1155MetadataURIUpgradeable).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 IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155ReceiverUpgradeable.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 IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n bytes4 response\n ) {\n if (response != IERC1155ReceiverUpgradeable.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 * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/extensions/ERC1155Burnable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {ERC1155} that allows token holders to destroy both their\n * own tokens and those that they have been approved to use.\n *\n * _Available since v3.1._\n */\nabstract contract ERC1155BurnableUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Burnable_init() internal onlyInitializing {\n }\n\n function __ERC1155Burnable_init_unchained() internal onlyInitializing {\n }\n function burn(address account, uint256 id, uint256 value) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burn(account, id, value);\n }\n\n function burnBatch(address account, uint256[] memory ids, uint256[] memory values) public virtual {\n require(\n account == _msgSender() || isApprovedForAll(account, _msgSender()),\n \"ERC1155: caller is not token owner or approved\"\n );\n\n _burnBatch(account, ids, values);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155SupplyUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155Supply_init() internal onlyInitializing {\n }\n\n function __ERC1155Supply_init_unchained() internal onlyInitializing {\n }\n mapping(uint256 => uint256) private _totalSupply;\n\n /**\n * @dev Total amount of tokens in with a given id.\n */\n function totalSupply(uint256 id) public view virtual returns (uint256) {\n return _totalSupply[id];\n }\n\n /**\n * @dev Indicates whether any token exist with a given id, or not.\n */\n function exists(uint256 id) public view virtual returns (bool) {\n return ERC1155SupplyUpgradeable.totalSupply(id) > 0;\n }\n\n /**\n * @dev See {ERC1155-_beforeTokenTransfer}.\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 override {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n if (from == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n _totalSupply[ids[i]] += amounts[i];\n }\n }\n\n if (to == address(0)) {\n for (uint256 i = 0; i < ids.length; ++i) {\n uint256 id = ids[i];\n uint256 amount = amounts[i];\n uint256 supply = _totalSupply[id];\n require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n unchecked {\n _totalSupply[id] = supply - amount;\n }\n }\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155URIStorage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../utils/StringsUpgradeable.sol\";\nimport \"../ERC1155Upgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev ERC1155 token with storage based token URI management.\n * Inspired by the ERC721URIStorage extension\n *\n * _Available since v4.6._\n */\nabstract contract ERC1155URIStorageUpgradeable is Initializable, ERC1155Upgradeable {\n function __ERC1155URIStorage_init() internal onlyInitializing {\n __ERC1155URIStorage_init_unchained();\n }\n\n function __ERC1155URIStorage_init_unchained() internal onlyInitializing {\n _baseURI = \"\";\n }\n using StringsUpgradeable for uint256;\n\n // Optional base URI\n string private _baseURI;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /**\n * @dev See {IERC1155MetadataURI-uri}.\n *\n * This implementation returns the concatenation of the `_baseURI`\n * and the token-specific uri if the latter is set\n *\n * This enables the following behaviors:\n *\n * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation\n * of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`\n * is empty per default);\n *\n * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`\n * which in most cases will contain `ERC1155._uri`;\n *\n * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a\n * uri value set, then the result is empty.\n */\n function uri(uint256 tokenId) public view virtual override returns (string memory) {\n string memory tokenURI = _tokenURIs[tokenId];\n\n // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).\n return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);\n }\n\n /**\n * @dev Sets `tokenURI` as the tokenURI of `tokenId`.\n */\n function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {\n _tokenURIs[tokenId] = tokenURI;\n emit URI(uri(tokenId), tokenId);\n }\n\n /**\n * @dev Sets `baseURI` as the `_baseURI` for all tokens\n */\n function _setBaseURI(string memory baseURI) internal virtual {\n _baseURI = baseURI;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[48] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.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 \"../IERC1155Upgradeable.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 IERC1155MetadataURIUpgradeable is IERC1155Upgradeable {\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-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.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/IERC165Upgradeable.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\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-upgradeable/token/ERC1155/IERC1155Upgradeable.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/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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-upgradeable/utils/AddressUpgradeable.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 AddressUpgradeable {\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-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.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 IERC165Upgradeable {\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-upgradeable/utils/math/MathUpgradeable.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 MathUpgradeable {\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-upgradeable/utils/math/SignedMathUpgradeable.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 SignedMathUpgradeable {\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-upgradeable/utils/StringsUpgradeable.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/MathUpgradeable.sol\";\nimport \"./math/SignedMathUpgradeable.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\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 = MathUpgradeable.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(SignedMathUpgradeable.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, MathUpgradeable.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" + }, + "@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" + }, + "@sandbox-smart-contracts/asset/contracts/Catalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\nimport {ERC1155Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol\";\nimport {\n AccessControlUpgradeable,\n ContextUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport {\n ERC1155BurnableUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155BurnableUpgradeable.sol\";\nimport {\n ERC1155SupplyUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155SupplyUpgradeable.sol\";\nimport {\n ERC1155URIStorageUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/ERC1155URIStorageUpgradeable.sol\";\nimport {\n IERC165Upgradeable,\n ERC2981Upgradeable\n} from \"@openzeppelin/contracts-upgradeable/token/common/ERC2981Upgradeable.sol\";\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {\n OperatorFiltererUpgradeable,\n IOperatorFilterRegistry\n} from \"@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol\";\nimport {\n RoyaltyDistributor\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol\";\nimport {\n IRoyaltyManager\n} from \"@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol\";\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {ERC2771Handler} from \"./ERC2771Handler.sol\";\nimport {ICatalyst} from \"./interfaces/ICatalyst.sol\";\n\n/// @title Catalyst\n/// @author The Sandbox\n/// @notice THis contract manages catalysts which are used to mint new assets.\n/// @dev An ERC1155 contract that manages catalysts, extends multiple OpenZeppelin contracts to\n/// provide a variety of features including, AccessControl, URIStorage, Burnable and more.\n/// The contract includes support for meta transactions.\ncontract Catalyst is\n ICatalyst,\n Initializable,\n ERC1155Upgradeable,\n ERC1155BurnableUpgradeable,\n ERC1155SupplyUpgradeable,\n ERC1155URIStorageUpgradeable,\n ERC2771Handler,\n AccessControlUpgradeable,\n OperatorFiltererUpgradeable,\n RoyaltyDistributor\n{\n bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n uint256 public tokenCount;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() {\n _disableInitializers();\n }\n\n modifier onlyValidId(uint256 tokenId) {\n require(tokenId > 0 && tokenId <= tokenCount, \"Catalyst: invalid catalyst id\");\n _;\n }\n\n /// @notice Initialize the contract, setting up initial values for various features.\n /// @param _baseUri The base URI for the token metadata, most likely set to ipfs://.\n /// @param _trustedForwarder The trusted forwarder for meta transactions.\n /// @param _subscription The subscription address.\n /// @param _defaultAdmin The default admin address.\n /// @param _defaultMinter The default minter address.\n /// @param _catalystIpfsCID The IPFS content identifiers for each catalyst.\n /// @param _royaltyManager, the address of the Manager contract for common royalty recipient\n function initialize(\n string memory _baseUri,\n address _trustedForwarder,\n address _subscription,\n address _defaultAdmin,\n address _defaultMinter,\n string[] memory _catalystIpfsCID,\n address _royaltyManager\n ) public initializer {\n require(bytes(_baseUri).length != 0, \"Catalyst: base uri can't be empty\");\n require(_trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero\");\n require(_subscription != address(0), \"Catalyst: subscription can't be zero\");\n require(_defaultAdmin != address(0), \"Catalyst: admin can't be zero\");\n require(_defaultMinter != address(0), \"Catalyst: minter can't be zero\");\n require(_royaltyManager != address(0), \"Catalyst: royalty manager can't be zero\");\n __ERC1155_init(_baseUri);\n __AccessControl_init();\n __ERC1155Burnable_init();\n __ERC1155Supply_init();\n __ERC1155URIStorage_init();\n __ERC2771Handler_initialize(_trustedForwarder);\n __OperatorFilterer_init(_subscription, true);\n _setBaseURI(_baseUri);\n _grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n _grantRole(MINTER_ROLE, _defaultMinter);\n __RoyaltyDistributor_init(_royaltyManager);\n for (uint256 i = 0; i < _catalystIpfsCID.length; i++) {\n require(bytes(_catalystIpfsCID[i]).length != 0, \"Catalyst: CID can't be empty\");\n _setURI(i, _catalystIpfsCID[i]);\n unchecked {tokenCount++;}\n }\n }\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external onlyRole(MINTER_ROLE) onlyValidId(id) {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(MINTER_ROLE) {\n for (uint256 i = 0; i < ids.length; i++) {\n require(ids[i] > 0 && ids[i] <= tokenCount, \"INVALID_CATALYST_ID\");\n }\n _mintBatch(to, ids, amounts, \"\");\n }\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external onlyRole(BURNER_ROLE) {\n _burn(account, id, amount);\n }\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external onlyRole(BURNER_ROLE) {\n _burnBatch(account, ids, amounts);\n }\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param catalystId The catalyst id to add\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(uint256 catalystId, string memory ipfsCID) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(catalystId > tokenCount, \"Catalyst: invalid catalyst id\");\n require(bytes(ipfsCID).length != 0, \"Catalyst: CID can't be empty\");\n tokenCount++;\n ERC1155URIStorageUpgradeable._setURI(catalystId, ipfsCID);\n emit NewCatalystTypeAdded(catalystId);\n }\n\n /// @notice Set a new trusted forwarder address, limited to DEFAULT_ADMIN_ROLE only\n /// @dev Change the address of the trusted forwarder for meta-TX\n /// @param trustedForwarder The new trustedForwarder\n function setTrustedForwarder(address trustedForwarder) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(trustedForwarder != address(0), \"Catalyst: trusted forwarder can't be zero address\");\n _trustedForwarder = trustedForwarder;\n emit TrustedForwarderChanged(trustedForwarder);\n }\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash)\n external\n onlyRole(DEFAULT_ADMIN_ROLE)\n onlyValidId(tokenId)\n {\n require(bytes(metadataHash).length != 0, \"Catalyst: metadataHash can't be empty\");\n _setURI(tokenId, metadataHash);\n }\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external onlyRole(DEFAULT_ADMIN_ROLE) {\n require(bytes(baseURI).length != 0, \"Catalyst: base uri can't be empty\");\n _setBaseURI(baseURI);\n }\n\n /// @notice returns full token URI, including baseURI and token metadata URI\n /// @param tokenId The token id to get URI for\n /// @return tokenURI the URI of the token\n function uri(uint256 tokenId)\n public\n view\n override(ERC1155Upgradeable, ERC1155URIStorageUpgradeable)\n returns (string memory)\n {\n return ERC1155URIStorageUpgradeable.uri(tokenId);\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (address) {\n return ERC2771Handler._msgSender();\n }\n\n /// @dev Needed for meta transactions (see EIP-2771)\n function _msgData() internal view virtual override(ContextUpgradeable, ERC2771Handler) returns (bytes calldata) {\n return ERC2771Handler._msgData();\n }\n\n /// @notice Transfers `value` tokens of type `id` from `from` to `to` (with safety call).\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param id the token type transfered.\n /// @param value amount of token transfered.\n /// @param data aditional data accompanying the transfer.\n function safeTransferFrom(\n address from,\n address to,\n uint256 id,\n uint256 value,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeTransferFrom(from, to, id, value, data);\n }\n\n /// @notice Transfers `values` tokens of type `ids` from `from` to `to` (with safety call).\n /// @dev call data should be optimized to order ids so packedBalance can be used efficiently.\n /// @param from address from which tokens are transfered.\n /// @param to address to which the token will be transfered.\n /// @param ids ids of each token type transfered.\n /// @param values amount of each token type transfered.\n /// @param data aditional data accompanying the transfer.\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] memory ids,\n uint256[] memory values,\n bytes memory data\n ) public override onlyAllowedOperator(from) {\n super._safeBatchTransferFrom(from, to, ids, values, data);\n }\n\n /// @notice Enable or disable approval for `operator` to manage all of the caller's tokens.\n /// @param operator address which will be granted rights to transfer all tokens of the caller.\n /// @param approved whether to approve or revoke\n function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {\n super._setApprovalForAll(_msgSender(), operator, approved);\n }\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 override(ERC1155Upgradeable, ERC1155SupplyUpgradeable) {\n super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId)\n public\n view\n override(ERC1155Upgradeable, AccessControlUpgradeable, RoyaltyDistributor)\n returns (bool)\n {\n return\n ERC1155Upgradeable.supportsInterface(interfaceId) ||\n AccessControlUpgradeable.supportsInterface(interfaceId) ||\n RoyaltyDistributor.supportsInterface(interfaceId);\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/ERC2771Handler.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\n/// @dev minimal ERC2771 handler to keep bytecode-size down\n/// based on: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/metatx/ERC2771Context.sol\n/// with an initializer for proxies and a mutable forwarder\n\nabstract contract ERC2771Handler {\n address internal _trustedForwarder;\n\n function __ERC2771Handler_initialize(address forwarder) internal {\n _trustedForwarder = forwarder;\n }\n\n function isTrustedForwarder(address forwarder) public view returns (bool) {\n return forwarder == _trustedForwarder;\n }\n\n function getTrustedForwarder() external view returns (address trustedForwarder) {\n return _trustedForwarder;\n }\n\n function _msgSender() internal view virtual returns (address sender) {\n if (isTrustedForwarder(msg.sender)) {\n // The assembly code is more direct than the Solidity version using `abi.decode`.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sender := shr(96, calldataload(sub(calldatasize(), 20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n if (isTrustedForwarder(msg.sender)) {\n return msg.data[:msg.data.length - 20];\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/interfaces/ICatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity 0.8.18;\n\ninterface ICatalyst {\n enum CatalystType {TSB_EXCLUSIVE, COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC}\n\n event TrustedForwarderChanged(address indexed newTrustedForwarderAddress);\n event NewCatalystTypeAdded(uint256 catalystId);\n event DefaultRoyaltyChanged(address indexed newDefaultRoyaltyRecipient, uint256 newDefaultRoyaltyAmount);\n\n /// @notice Mints a new token, limited to MINTER_ROLE only\n /// @param to The address that will own the minted token\n /// @param id The token id to mint\n /// @param amount The amount to be minted\n function mint(\n address to,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Mints a batch of tokens, limited to MINTER_ROLE only\n /// @param to The address that will own the minted tokens\n /// @param ids The token ids to mint\n /// @param amounts The amounts to be minted per token id\n function mintBatch(\n address to,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Burns a specified amount of tokens from a specific address\n /// @param account The address to burn from\n /// @param id The token id to burn\n /// @param amount The amount to be burned\n function burnFrom(\n address account,\n uint256 id,\n uint256 amount\n ) external;\n\n /// @notice Burns a batch of tokens from a specific address\n /// @param account The address to burn from\n /// @param ids The token ids to burn\n /// @param amounts The amounts to be burned\n function burnBatchFrom(\n address account,\n uint256[] memory ids,\n uint256[] memory amounts\n ) external;\n\n /// @notice Add a new catalyst type, limited to DEFAULT_ADMIN_ROLE only\n /// @param catalystId The catalyst id to add\n /// @param ipfsCID The royalty bps for the catalyst\n function addNewCatalystType(uint256 catalystId, string memory ipfsCID) external;\n\n /// @notice Set a new URI for specific tokenid\n /// @param tokenId The token id to set URI for\n /// @param metadataHash The new URI\n function setMetadataHash(uint256 tokenId, string memory metadataHash) external;\n\n /// @notice Set a new base URI\n /// @param baseURI The new base URI\n function setBaseURI(string memory baseURI) external;\n}\n" + }, + "@sandbox-smart-contracts/asset/contracts/mock/MockCatalyst.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity 0.8.18;\n\nimport {Catalyst, IOperatorFilterRegistry} from \"../Catalyst.sol\";\n\ncontract MockCatalyst is Catalyst {\n /// @notice sets registry and subscribe to subscription\n /// @param registry address of registry\n /// @param subscription address to subscribe\n function setRegistryAndSubscribe(address registry, address subscription) external {\n operatorFilterRegistry = IOperatorFilterRegistry(registry);\n operatorFilterRegistry.registerAndSubscribe(address(this), subscription);\n }\n\n /// @notice Mint new tokens with out minter role\n /// @param to The address of the recipient\n /// @param id The id of the token to mint\n /// @param amount The amount of the token to mint\n function mintWithoutMinterRole(\n address to,\n uint256 id,\n uint256 amount\n ) external {\n _mint(to, id, amount, \"\");\n }\n\n /// @notice set approval for asset transfer without filteration\n /// @param operator operator to be approved\n /// @param approved bool value for giving (true) and canceling (false) approval\n function setApprovalForAllWithoutFilter(address operator, bool approved) public virtual {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/interfaces/IOperatorFilterRegistry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IOperatorFilterRegistry {\n /**\n * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns\n * true if supplied registrant address is not registered.\n */\n function isOperatorAllowed(address registrant, address operator) external view returns (bool);\n\n /**\n * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.\n */\n function register(address registrant) external;\n\n /**\n * @notice Registers an address with the registry and \"subscribes\" to another address's filtered operators and codeHashes.\n */\n function registerAndSubscribe(address registrant, address subscription) external;\n\n /**\n * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another\n * address without subscribing.\n */\n function registerAndCopyEntries(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.\n * Note that this does not remove any filtered addresses or codeHashes.\n * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.\n */\n function unregister(address addr) external;\n\n /**\n * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.\n */\n function updateOperator(\n address registrant,\n address operator,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.\n */\n function updateOperators(\n address registrant,\n address[] calldata operators,\n bool filtered\n ) external;\n\n /**\n * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.\n */\n function updateCodeHash(\n address registrant,\n bytes32 codehash,\n bool filtered\n ) external;\n\n /**\n * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.\n */\n function updateCodeHashes(\n address registrant,\n bytes32[] calldata codeHashes,\n bool filtered\n ) external;\n\n /**\n * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous\n * subscription if present.\n * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,\n * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be\n * used.\n */\n function subscribe(address registrant, address registrantToSubscribe) external;\n\n /**\n * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.\n */\n function unsubscribe(address registrant, bool copyExistingEntries) external;\n\n /**\n * @notice Get the subscription address of a given registrant, if any.\n */\n function subscriptionOf(address addr) external returns (address registrant);\n\n /**\n * @notice Get the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscribers(address registrant) external returns (address[] memory);\n\n /**\n * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.\n * Note that order is not guaranteed as updates are made.\n */\n function subscriberAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.\n */\n function copyEntriesOf(address registrant, address registrantToCopy) external;\n\n /**\n * @notice Returns true if operator is filtered by a given address or its subscription.\n */\n function isOperatorFiltered(address registrant, address operator) external returns (bool);\n\n /**\n * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.\n */\n function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);\n\n /**\n * @notice Returns true if a codeHash is filtered by a given address or its subscription.\n */\n function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);\n\n /**\n * @notice Returns a list of filtered operators for a given address or its subscription.\n */\n function filteredOperators(address addr) external returns (address[] memory);\n\n /**\n * @notice Returns the set of filtered codeHashes for a given address or its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashes(address addr) external returns (bytes32[] memory);\n\n /**\n * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredOperatorAt(address registrant, uint256 index) external returns (address);\n\n /**\n * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or\n * its subscription.\n * Note that order is not guaranteed as updates are made.\n */\n function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);\n\n /**\n * @notice Returns true if an address has registered\n */\n function isRegistered(address addr) external returns (bool);\n\n /**\n * @dev Convenience method to compute the code hash of an arbitrary contract\n */\n function codeHashOf(address addr) external returns (bytes32);\n}\n" + }, + "@sandbox-smart-contracts/dependency-operator-filter/contracts/OperatorFiltererUpgradeable.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {Initializable} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {IOperatorFilterRegistry} from \"./interfaces/IOperatorFilterRegistry.sol\";\n\n///@title OperatorFiltererUpgradeable\n///@author The SandBox\n///@notice This contract would subscibe or copy or just to the subscription provided or just register to default subscription list. The operator filter registry's addess could be set using a setter which could be implemented in inherting contract\nabstract contract OperatorFiltererUpgradeable is Initializable {\n IOperatorFilterRegistry public operatorFilterRegistry;\n\n function __OperatorFilterer_init(address subscriptionOrRegistrantToCopy, bool subscribe) internal onlyInitializing {\n operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); // Address of the operator filterer registry\n // If an inheriting token contract is deployed to a network without the registry deployed, the modifier\n // will not revert, but the contract will need to be registered with the registry once it is deployed in\n // order for the modifier to filter addresses.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isRegistered(address(this))) {\n if (subscribe) {\n operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);\n } else {\n if (subscriptionOrRegistrantToCopy != address(0)) {\n operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);\n } else {\n operatorFilterRegistry.register(address(this));\n }\n }\n }\n }\n }\n\n modifier onlyAllowedOperator(address from) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n // Allow spending tokens from addresses with balance\n // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred\n // from an EOA.\n if (from == msg.sender) {\n _;\n return;\n }\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n\n modifier onlyAllowedOperatorApproval(address operator) virtual {\n // Check registry code length to facilitate testing in environments without a deployed registry.\n if (address(operatorFilterRegistry).code.length > 0) {\n if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {\n revert(\"Operator Not Allowed\");\n }\n }\n _;\n }\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/interfaces/IRoyaltyManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport {Recipient} from \"@manifoldxyz/royalty-registry-solidity/contracts/overrides/IRoyaltySplitter.sol\";\n\ninterface IRoyaltyManager {\n event RecipientSet(address commonRecipient);\n\n event SplitSet(uint16 commonSplit);\n\n event RoyaltySet(uint16 royaltyBps, address contractAddress);\n\n function setRecipient(address payable _commonRecipient) external;\n\n function setSplit(uint16 commonSplit) external;\n\n function getCommonRecipient() external view returns (Recipient memory recipient);\n\n function getCreatorSplit() external view returns (uint16);\n\n function getRoyaltyInfo() external view returns (address, uint16);\n\n function deploySplitter(address creator, address payable recipient) external returns (address payable);\n\n function getCreatorRoyaltySplitter(address creator) external view returns (address payable);\n}\n" + }, + "@sandbox-smart-contracts/dependency-royalty-management/contracts/RoyaltyDistributor.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC2981Upgradeable} from \"@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol\";\nimport {IRoyaltyManager} from \"./interfaces/IRoyaltyManager.sol\";\n\ncontract RoyaltyDistributor is IERC2981Upgradeable {\n uint16 internal constant TOTAL_BASIS_POINTS = 10000;\n IRoyaltyManager public royaltyManager;\n\n function __RoyaltyDistributor_init(address _royaltyManager) internal {\n royaltyManager = IRoyaltyManager(_royaltyManager);\n }\n\n /// @notice Returns how much royalty is owed and to whom based on ERC2981\n /// @dev tokenId is one of the EIP2981 args for this function can't be removed\n /// @param _salePrice the price of token on which the royalty is calculated\n /// @return receiver the receiver of royalty\n /// @return royaltyAmount the amount of royalty\n function royaltyInfo(\n uint256, /*_tokenId */\n uint256 _salePrice\n ) external view returns (address receiver, uint256 royaltyAmount) {\n uint16 royaltyBps;\n (receiver, royaltyBps) = royaltyManager.getRoyaltyInfo();\n royaltyAmount = (_salePrice * royaltyBps) / TOTAL_BASIS_POINTS;\n return (receiver, royaltyAmount);\n }\n\n /// @notice Query if a contract implements interface `id`.\n /// @param interfaceId the interface identifier, as specified in ERC-165.\n /// @return `true` if the contract implements `id`.\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC2981Upgradeable).interfaceId;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 2000 + }, + "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/packages/deploy/deployments/polygon/DEFAULT_SUBSCRIPTION.json b/packages/deploy/deployments/polygon/DEFAULT_SUBSCRIPTION.json new file mode 100644 index 0000000000..fce80b9790 --- /dev/null +++ b/packages/deploy/deployments/polygon/DEFAULT_SUBSCRIPTION.json @@ -0,0 +1,87 @@ +{ + "address": "0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6", + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/packages/deploy/deployments/polygon/OPERATOR_FILTER_REGISTRY.json b/packages/deploy/deployments/polygon/OPERATOR_FILTER_REGISTRY.json new file mode 100644 index 0000000000..06f9fe066b --- /dev/null +++ b/packages/deploy/deployments/polygon/OPERATOR_FILTER_REGISTRY.json @@ -0,0 +1,498 @@ +{ + "address": "0x000000000000AAeB6D7670E522A718067333cd4E", + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "AddressAlreadyFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "filtered", "type": "address" } + ], + "name": "AddressFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "AddressNotFiltered", + "type": "error" + }, + { "inputs": [], "name": "AlreadyRegistered", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "name": "AlreadySubscribed", + "type": "error" + }, + { "inputs": [], "name": "CannotCopyFromSelf", "type": "error" }, + { "inputs": [], "name": "CannotFilterEOAs", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "CannotSubscribeToRegistrantWithSubscription", + "type": "error" + }, + { "inputs": [], "name": "CannotSubscribeToSelf", "type": "error" }, + { "inputs": [], "name": "CannotSubscribeToZeroAddress", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "name": "CannotUpdateWhileSubscribed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "CodeHashAlreadyFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "CodeHashFiltered", + "type": "error" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "CodeHashNotFiltered", + "type": "error" + }, + { "inputs": [], "name": "NotOwnable", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "NotRegistered", + "type": "error" + }, + { "inputs": [], "name": "NotSubscribed", "type": "error" }, + { "inputs": [], "name": "OnlyAddressOrOwner", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "codeHash", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "CodeHashUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "codeHashes", + "type": "bytes32[]" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "CodeHashesUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "OperatorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "operators", + "type": "address[]" + }, + { + "indexed": true, + "internalType": "bool", + "name": "filtered", + "type": "bool" + } + ], + "name": "OperatorsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "registered", + "type": "bool" + } + ], + "name": "RegistrationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "registrant", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "subscription", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "subscribed", + "type": "bool" + } + ], + "name": "SubscriptionUpdated", + "type": "event" + }, + { + "inputs": [{ "internalType": "address", "name": "a", "type": "address" }], + "name": "codeHashOf", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "registrantToCopy", + "type": "address" + } + ], + "name": "copyEntriesOf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "filteredCodeHashAt", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "filteredCodeHashes", + "outputs": [ + { "internalType": "bytes32[]", "name": "", "type": "bytes32[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "filteredOperatorAt", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "filteredOperators", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" } + ], + "name": "isCodeHashFiltered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "operatorWithCode", + "type": "address" + } + ], + "name": "isCodeHashOfFiltered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "isOperatorAllowed", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "isOperatorFiltered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "isRegistered", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "register", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "registrantToCopy", + "type": "address" + } + ], + "name": "registerAndCopyEntries", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "name": "registerAndSubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address", + "name": "newSubscription", + "type": "address" + } + ], + "name": "subscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "subscriberAt", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "subscribers", + "outputs": [ + { "internalType": "address[]", "name": "", "type": "address[]" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "subscriptionOf", + "outputs": [ + { "internalType": "address", "name": "subscription", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" } + ], + "name": "unregister", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "bool", + "name": "copyExistingEntries", + "type": "bool" + } + ], + "name": "unsubscribe", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "bytes32", "name": "codeHash", "type": "bytes32" }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateCodeHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "bytes32[]", + "name": "codeHashes", + "type": "bytes32[]" + }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateCodeHashes", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "registrant", "type": "address" }, + { + "internalType": "address[]", + "name": "operators", + "type": "address[]" + }, + { "internalType": "bool", "name": "filtered", "type": "bool" } + ], + "name": "updateOperators", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/packages/deploy/hardhat.config.ts b/packages/deploy/hardhat.config.ts index cf76b49fea..35df72219b 100644 --- a/packages/deploy/hardhat.config.ts +++ b/packages/deploy/hardhat.config.ts @@ -8,7 +8,10 @@ import './tasks/importedPackages'; // Package name : solidity source code path const importedPackages = { + '@sandbox-smart-contracts/asset': 'contracts/', '@sandbox-smart-contracts/giveaway': 'contracts/SignedMultiGiveaway.sol', + '@sandbox-smart-contracts/dependency-operator-filter': 'contracts/', + '@sandbox-smart-contracts/dependency-royalty-management': 'contracts/', }; const namedAccounts = { @@ -34,6 +37,8 @@ const namedAccounts = { polygon: 'sandAdmin', }, + filterOperatorSubscription: 'deployer', + upgradeAdmin: 'sandAdmin', multiGiveawayAdmin: { @@ -57,6 +62,7 @@ const namedAccounts = { mintingFeeCollector: 'sandAdmin', // will receiver the fee from Asset minting sandBeneficiary: 'sandAdmin', // will be the owner of all initial SAND assetAdmin: 'sandAdmin', // can add super operator and change admin to Asset + assetPauser: 'sandAdmin', // can pause AssetCreate and AssetReveal assetMinterAdmin: 'sandAdmin', // can set metaTxProcessors & types assetBouncerAdmin: 'sandAdmin', // setup the contract allowed to mint Assets sandSaleAdmin: 'sandAdmin', // can pause the sandSale and withdraw SAND @@ -64,7 +70,11 @@ const namedAccounts = { defaultMinterAdmin: 'sandAdmin', // can change the fees genesisMinter: 'sandAdmin', // the first account allowed to mint genesis Assets assetAuctionFeeCollector: 'sandSaleBeneficiary', // collect fees from asset auctions - assetAuctionAdmin: 'sandAdmin', // can change fee collector + assetAuctionAdmin: 'sandAdmin', // can change fee collector, + + commonRoyaltyReceiver: 'treasury', // The Sandbox royalty receiver + royaltyManagerAdmin: 'sandAdmin', // default admin for RoyaltyManager contract + contractRoyaltySetter: 'sandAdmin', // can set the EIP 2981 royalty split for contracts via RoyaltyManager sandSaleBeneficiary: { default: 3, diff --git a/packages/deploy/package.json b/packages/deploy/package.json index 05cb15f5d1..e3fe5eea8c 100644 --- a/packages/deploy/package.json +++ b/packages/deploy/package.json @@ -15,6 +15,9 @@ "homepage": "https://github.com/thesandboxgame/sandbox-smart-contracts#readme", "private": true, "dependencies": { + "@sandbox-smart-contracts/asset": "*", + "@sandbox-smart-contracts/dependency-operator-filter": "*", + "@sandbox-smart-contracts/dependency-royalty-management": "*", "@sandbox-smart-contracts/giveaway": "0.0.3" }, "files": [ diff --git a/packages/deploy/test/asset/Asset.test.ts b/packages/deploy/test/asset/Asset.test.ts new file mode 100644 index 0000000000..80a034f1c8 --- /dev/null +++ b/packages/deploy/test/asset/Asset.test.ts @@ -0,0 +1,263 @@ +import {OPERATOR_FILTER_REGISTRY} from './../../../asset/data/constants'; +import {DEFAULT_BPS} from '../../deploy/400_asset/407_asset_setup'; +import {expect} from 'chai'; +import {deployments} from 'hardhat'; +import {OperatorFilterRegistryBytecode} from '../../utils/bytecodes'; +import {OperatorFilterRegistry_ABI} from '../../utils/abi'; + +const setupTest = deployments.createFixture( + async ({deployments, network, getNamedAccounts, ethers}) => { + const {deployer, assetAdmin, filterOperatorSubscription, sandAdmin} = + await getNamedAccounts(); + await network.provider.send('hardhat_setCode', [ + OPERATOR_FILTER_REGISTRY, + OperatorFilterRegistryBytecode, + ]); + const OperatorFilterRegistryContract = await ethers.getContractAt( + OperatorFilterRegistry_ABI, + OPERATOR_FILTER_REGISTRY + ); + + await deployments.fixture([ + 'MockERC1155MarketPlace1', + 'MockERC1155MarketPlace2', + 'MockERC1155MarketPlace3', + 'MockERC1155MarketPlace4', + ]); + + const MockERC1155MarketPlace1 = await deployments.get( + 'MockERC1155MarketPlace1' + ); + const MockERC1155MarketPlace2 = await deployments.get( + 'MockERC1155MarketPlace2' + ); + const MockERC1155MarketPlace3 = await deployments.get( + 'MockERC1155MarketPlace3' + ); + const MockERC1155MarketPlace4 = await deployments.get( + 'MockERC1155MarketPlace4' + ); + + const deployerSigner = await ethers.getSigner(deployer); + + const tx1 = await OperatorFilterRegistryContract.connect( + deployerSigner + ).register(filterOperatorSubscription); + + await tx1.wait(); + + await network.provider.send('hardhat_setBalance', [ + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6', + '0xDE0B6B3A7640000', + ]); + await network.provider.request({ + method: 'hardhat_impersonateAccount', + params: ['0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'], + }); + const signer = await ethers.getSigner( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6' + ); + const tx = await OperatorFilterRegistryContract.connect(signer).register( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6' + ); + await tx.wait(); + const MockMarketPlace1CodeHash = + await OperatorFilterRegistryContract.connect(signer).codeHashOf( + MockERC1155MarketPlace1.address + ); + const MockMarketPlace2CodeHash = + await OperatorFilterRegistryContract.connect(signer).codeHashOf( + MockERC1155MarketPlace2.address + ); + + const subscriptionSigner = await ethers.getSigner( + filterOperatorSubscription + ); + const tx2 = await OperatorFilterRegistryContract.connect( + subscriptionSigner + ).updateOperators( + filterOperatorSubscription, + [MockERC1155MarketPlace1.address, MockERC1155MarketPlace2.address], + true + ); + await tx2.wait(); + const tx3 = await OperatorFilterRegistryContract.connect( + subscriptionSigner + ).updateCodeHashes( + filterOperatorSubscription, + [MockMarketPlace1CodeHash, MockMarketPlace2CodeHash], + true + ); + await tx3.wait(); + await network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: ['0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'], + }); + + await deployments.fixture(); + const Asset = await deployments.get('Asset'); + const AssetContract = await ethers.getContractAt(Asset.abi, Asset.address); + const AssetCreate = await deployments.get('AssetCreate'); + const AssetCreateContract = await ethers.getContractAt( + AssetCreate.abi, + AssetCreate.address + ); + + const RoyaltyManager = await deployments.get('RoyaltyManager'); + const RoyaltyManagerContract = await ethers.getContractAt( + RoyaltyManager.abi, + RoyaltyManager.address + ); + const TRUSTED_FORWARDER_Data = await deployments.get( + 'TRUSTED_FORWARDER_V2' + ); + const TRUSTED_FORWARDER = await ethers.getContractAt( + TRUSTED_FORWARDER_Data.abi, + TRUSTED_FORWARDER_Data.address + ); + + // grant moderator role to the assetAdmin + const adminSigner = await ethers.getSigner(assetAdmin); + const moderatorRole = await AssetContract.MODERATOR_ROLE(); + await AssetContract.connect(adminSigner).grantRole( + moderatorRole, + assetAdmin + ); + // set tokenURI for tokenId 1 for baseURI test + const mockMetadataHash = 'QmQ6BFzGGAU7JdkNJmvkEVjvqKC4VCGb3qoDnjAQWHexxD'; + await AssetContract.connect(adminSigner).setTokenURI(1, mockMetadataHash); + + return { + AssetContract, + AssetCreateContract, + RoyaltyManagerContract, + deployer, + sandAdmin, + filterOperatorSubscription, + TRUSTED_FORWARDER, + OPERATOR_FILTER_REGISTRY, + OperatorFilterRegistryContract, + mockMetadataHash, + MockERC1155MarketPlace1, + MockERC1155MarketPlace2, + MockERC1155MarketPlace3, + MockERC1155MarketPlace4, + }; + } +); + +describe('Asset', function () { + describe('Roles', function () { + it('Admin', async function () { + const {AssetContract, sandAdmin} = await setupTest(); + const defaultAdminRole = await AssetContract.DEFAULT_ADMIN_ROLE(); + expect(await AssetContract.hasRole(defaultAdminRole, sandAdmin)).to.be + .true; + }); + it('Minter', async function () { + const {AssetContract, AssetCreateContract} = await setupTest(); + const minterRole = await AssetContract.MINTER_ROLE(); + expect( + await AssetContract.hasRole(minterRole, AssetCreateContract.address) + ).to.be.true; + }); + it('Burner', async function () { + // TODO Update when AssetRecycle is deployed + }); + it('Moderator', async function () { + const {AssetContract, sandAdmin} = await setupTest(); + const moderatorRole = await AssetContract.MODERATOR_ROLE(); + expect(await AssetContract.hasRole(moderatorRole, sandAdmin)).to.be.true; + }); + }); + describe("Asset's Metadata", function () { + it('Asset base URI is set correctly', async function () { + const {AssetContract, mockMetadataHash} = await setupTest(); + expect(await AssetContract.uri(1)).to.be.equal( + 'ipfs://' + mockMetadataHash + ); + }); + }); + describe('Royalties', function () { + it('Contract is registered on RoyaltyManager', async function () { + const {RoyaltyManagerContract, AssetContract} = await setupTest(); + expect( + await RoyaltyManagerContract.getContractRoyalty(AssetContract.address) + ).to.be.equal(DEFAULT_BPS); + }); + }); + describe('Trusted Forwarder', function () { + it('Trusted forwarder address is set correctly', async function () { + const {AssetContract, TRUSTED_FORWARDER} = await setupTest(); + expect(await AssetContract.getTrustedForwarder()).to.be.equal( + TRUSTED_FORWARDER.address + ); + }); + }); + describe('Operator Filter Registry', function () { + it('Asset contract is registered correctly', async function () { + const {OperatorFilterRegistryContract, AssetContract} = await setupTest(); + expect( + await OperatorFilterRegistryContract.isRegistered(AssetContract.address) + ).to.be.true; + }); + it('Asset contract is subscribed to correct address', async function () { + const { + OperatorFilterRegistryContract, + AssetContract, + filterOperatorSubscription, + } = await setupTest(); + expect( + await OperatorFilterRegistryContract.subscriptionOf( + AssetContract.address + ) + ).to.be.equal(filterOperatorSubscription); + }); + it('asset contract has correct market places black listed', async function () { + const { + OperatorFilterRegistryContract, + AssetContract, + MockERC1155MarketPlace1, + MockERC1155MarketPlace2, + MockERC1155MarketPlace3, + MockERC1155MarketPlace4, + } = await setupTest(); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + AssetContract.address, + MockERC1155MarketPlace1.address + ), + 'MarketPlace1 should be filtered' + ).to.be.equal(true); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + AssetContract.address, + MockERC1155MarketPlace2.address + ), + 'MarketPlace2 should be filtered' + ).to.be.equal(true); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + AssetContract.address, + MockERC1155MarketPlace3.address + ), + 'MarketPlace3 should not be filtered' + ).to.be.equal(false); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + AssetContract.address, + MockERC1155MarketPlace4.address + ), + 'MarketPlace4 should not be filtered' + ).to.be.equal(false); + }); + }); + describe('MultiRoyaltyDistributor', function () { + it('RoyaltyManager contract is set correctly', async function () { + const {AssetContract, RoyaltyManagerContract} = await setupTest(); + expect(await AssetContract.getRoyaltyManager()).to.be.equal( + RoyaltyManagerContract.address + ); + }); + }); +}); diff --git a/packages/deploy/test/asset/AssetCreate.test.ts b/packages/deploy/test/asset/AssetCreate.test.ts new file mode 100644 index 0000000000..0fdd78c51a --- /dev/null +++ b/packages/deploy/test/asset/AssetCreate.test.ts @@ -0,0 +1,124 @@ +import {expect} from 'chai'; +import {deployments} from 'hardhat'; + +const setupTest = deployments.createFixture( + async ({deployments, getNamedAccounts, ethers}) => { + const {assetAdmin, backendAuthWallet, assetPauser} = + await getNamedAccounts(); + await deployments.fixture(); + const Asset = await deployments.get('Asset'); + const AssetContract = await ethers.getContractAt('Asset', Asset.address); + const AssetCreate = await deployments.get('AssetCreate'); + const AssetCreateContract = await ethers.getContractAt( + 'AssetCreate', + AssetCreate.address + ); + const Catalyst = await deployments.get('Catalyst'); + const CatalystContract = await ethers.getContractAt( + 'Catalyst', + Catalyst.address + ); + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + const AuthSuperValidator = await deployments.get('AuthSuperValidator'); + const AuthSuperValidatorContract = await ethers.getContractAt( + 'AuthSuperValidator', + AuthSuperValidator.address + ); + + return { + AssetContract, + AssetCreateContract, + CatalystContract, + TRUSTED_FORWARDER, + AuthSuperValidatorContract, + assetAdmin, + backendAuthWallet, + assetPauser, + }; + } +); + +describe('Asset Create', function () { + describe('Contract references', function () { + it('AuthSuperValidator', async function () { + const {AssetCreateContract, AuthSuperValidatorContract} = + await setupTest(); + expect(await AssetCreateContract.getAuthValidator()).to.be.equal( + AuthSuperValidatorContract.address + ); + }); + it('Asset', async function () { + const {AssetCreateContract, AssetContract} = await setupTest(); + expect(await AssetCreateContract.getAssetContract()).to.be.equal( + AssetContract.address + ); + }); + it('Catalyst', async function () { + const {AssetCreateContract, CatalystContract} = await setupTest(); + expect(await AssetCreateContract.getCatalystContract()).to.be.equal( + CatalystContract.address + ); + }); + }); + describe('Roles', function () { + it('Admin', async function () { + const {AssetCreateContract, assetAdmin} = await setupTest(); + const defaultAdminRole = await AssetCreateContract.DEFAULT_ADMIN_ROLE(); + expect(await AssetCreateContract.hasRole(defaultAdminRole, assetAdmin)).to + .be.true; + }); + it("Asset's Minter role is granted to AssetCreate", async function () { + const {AssetCreateContract, AssetContract} = await setupTest(); + const minterRole = await AssetContract.MINTER_ROLE(); + expect( + await AssetContract.hasRole(minterRole, AssetCreateContract.address) + ).to.be.true; + }); + it("Catalyst's Burner role is granted to AssetCreate", async function () { + const {AssetCreateContract, CatalystContract} = await setupTest(); + const burnerRole = await CatalystContract.BURNER_ROLE(); + expect( + await CatalystContract.hasRole(burnerRole, AssetCreateContract.address) + ).to.be.true; + }); + it('AuthSuperValidator signer is set to backendAuthWallet', async function () { + const { + AssetCreateContract, + AuthSuperValidatorContract, + backendAuthWallet, + } = await setupTest(); + expect( + await AuthSuperValidatorContract.getSigner(AssetCreateContract.address) + ).to.be.equal(backendAuthWallet); + expect( + await AuthSuperValidatorContract.getSigner(AssetCreateContract.address) + ).to.be.equal(backendAuthWallet); + }); + it('Pauser role is granted to assetPauser', async function () { + const {AssetCreateContract, assetPauser} = await setupTest(); + const pauserRole = await AssetCreateContract.PAUSER_ROLE(); + expect(await AssetCreateContract.hasRole(pauserRole, assetPauser)).to.be + .true; + }); + }); + describe('EIP712', function () { + it("name is 'Sandbox Asset Create'", async function () { + const {AssetCreateContract} = await setupTest(); + const eip712Domain = await AssetCreateContract.eip712Domain(); + expect(eip712Domain.name).to.be.equal('Sandbox Asset Create'); + }); + it("version is '1.0'", async function () { + const {AssetCreateContract} = await setupTest(); + const eip712Domain = await AssetCreateContract.eip712Domain(); + expect(eip712Domain.version).to.be.equal('1.0'); + }); + }); + describe('Trusted Forwarder', function () { + it('Trusted forwarder address is set correctly', async function () { + const {AssetCreateContract, TRUSTED_FORWARDER} = await setupTest(); + expect(await AssetCreateContract.getTrustedForwarder()).to.be.equal( + TRUSTED_FORWARDER.address + ); + }); + }); +}); diff --git a/packages/deploy/test/asset/AssetReveal.test.ts b/packages/deploy/test/asset/AssetReveal.test.ts new file mode 100644 index 0000000000..4a16c2a573 --- /dev/null +++ b/packages/deploy/test/asset/AssetReveal.test.ts @@ -0,0 +1,111 @@ +import {expect} from 'chai'; +import {deployments} from 'hardhat'; + +const setupTest = deployments.createFixture( + async ({deployments, getNamedAccounts, ethers}) => { + const {assetAdmin, backendAuthWallet, assetPauser} = + await getNamedAccounts(); + await deployments.fixture('Asset'); + const Asset = await deployments.get('Asset'); + const AssetContract = await ethers.getContractAt('Asset', Asset.address); + const AssetReveal = await deployments.get('AssetReveal'); + const AssetRevealContract = await ethers.getContractAt( + 'AssetReveal', + AssetReveal.address + ); + const Catalyst = await deployments.get('Catalyst'); + const CatalystContract = await ethers.getContractAt( + 'Catalyst', + Catalyst.address + ); + const TRUSTED_FORWARDER = await deployments.get('TRUSTED_FORWARDER_V2'); + const AuthSuperValidator = await deployments.get('AuthSuperValidator'); + const AuthSuperValidatorContract = await ethers.getContractAt( + 'AuthSuperValidator', + AuthSuperValidator.address + ); + + return { + AssetContract, + AssetRevealContract, + CatalystContract, + TRUSTED_FORWARDER, + AuthSuperValidatorContract, + assetAdmin, + backendAuthWallet, + assetPauser, + }; + } +); + +describe('Asset Reveal', function () { + describe('Contract references', function () { + it('AuthSuperValidator', async function () { + const {AssetRevealContract, AuthSuperValidatorContract} = + await setupTest(); + expect(await AssetRevealContract.getAuthValidator()).to.be.equal( + AuthSuperValidatorContract.address + ); + }); + it('Asset', async function () { + const {AssetRevealContract, AssetContract} = await setupTest(); + expect(await AssetRevealContract.getAssetContract()).to.be.equal( + AssetContract.address + ); + }); + }); + describe('Roles', function () { + it('Admin', async function () { + const {AssetRevealContract, assetAdmin} = await setupTest(); + const defaultAdminRole = await AssetRevealContract.DEFAULT_ADMIN_ROLE(); + expect(await AssetRevealContract.hasRole(defaultAdminRole, assetAdmin)).to + .be.true; + }); + it("Asset's Minter role is granted to AssetReveal", async function () { + const {AssetRevealContract, AssetContract} = await setupTest(); + const minterRole = await AssetContract.MINTER_ROLE(); + expect( + await AssetContract.hasRole(minterRole, AssetRevealContract.address) + ).to.be.true; + }); + it('AuthSuperValidator signer is set to backendAuthWallet', async function () { + const { + AssetRevealContract, + AuthSuperValidatorContract, + backendAuthWallet, + } = await setupTest(); + expect( + await AuthSuperValidatorContract.getSigner(AssetRevealContract.address) + ).to.be.equal(backendAuthWallet); + expect( + await AuthSuperValidatorContract.getSigner(AssetRevealContract.address) + ).to.be.equal(backendAuthWallet); + }); + it('Pauser role is granted to assetPauser', async function () { + const {AssetRevealContract, assetPauser} = await setupTest(); + const pauserRole = await AssetRevealContract.PAUSER_ROLE(); + expect(await AssetRevealContract.hasRole(pauserRole, assetPauser)).to.be + .true; + }); + }); + describe('EIP712', function () { + it("name is 'Sandbox Asset Reveal'", async function () { + const {AssetRevealContract} = await setupTest(); + const eip712Domain = await AssetRevealContract.eip712Domain(); + expect(eip712Domain.name).to.be.equal('Sandbox Asset Reveal'); + }); + it("version is '1.0'", async function () { + const {AssetRevealContract} = await setupTest(); + const eip712Domain = await AssetRevealContract.eip712Domain(); + expect(eip712Domain.version).to.be.equal('1.0'); + }); + }); + describe('Trusted Forwarder', function () { + it('Trusted forwarder address is set correctly', async function () { + const {AssetRevealContract, TRUSTED_FORWARDER} = await setupTest(); + expect(await AssetRevealContract.getTrustedForwarder()).to.be.equal( + TRUSTED_FORWARDER.address + ); + }); + }); +}); diff --git a/packages/deploy/test/catalyst/catalyst.test.ts b/packages/deploy/test/catalyst/catalyst.test.ts new file mode 100644 index 0000000000..4f3c519dee --- /dev/null +++ b/packages/deploy/test/catalyst/catalyst.test.ts @@ -0,0 +1,226 @@ +import {royaltyAmount} from '../../deploy/300_catalyst/302_catalyst_setup'; +import {OPERATOR_FILTER_REGISTRY} from './../../../asset/data/constants'; +import {expect} from 'chai'; +import {OperatorFilterRegistryBytecode} from '../../utils/bytecodes'; +import {OperatorFilterRegistry_ABI} from '../../utils/abi'; +import {deployments} from 'hardhat'; + +const setupTest = deployments.createFixture( + async ({deployments, network, getNamedAccounts, ethers}) => { + const {catalystAdmin, catalystMinter} = await getNamedAccounts(); + await network.provider.send('hardhat_setCode', [ + OPERATOR_FILTER_REGISTRY, + OperatorFilterRegistryBytecode, + ]); + const OperatorFilterRegistryContract = await ethers.getContractAt( + OperatorFilterRegistry_ABI, + OPERATOR_FILTER_REGISTRY + ); + + await deployments.fixture([ + 'MockERC1155MarketPlace1', + 'MockERC1155MarketPlace2', + 'MockERC1155MarketPlace3', + 'MockERC1155MarketPlace4', + ]); + + const MockERC1155MarketPlace1 = await deployments.get( + 'MockERC1155MarketPlace1' + ); + const MockERC1155MarketPlace2 = await deployments.get( + 'MockERC1155MarketPlace2' + ); + const MockERC1155MarketPlace3 = await deployments.get( + 'MockERC1155MarketPlace3' + ); + const MockERC1155MarketPlace4 = await deployments.get( + 'MockERC1155MarketPlace4' + ); + await network.provider.send('hardhat_setBalance', [ + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6', + '0xDE0B6B3A7640000', + ]); + await network.provider.request({ + method: 'hardhat_impersonateAccount', + params: ['0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'], + }); + const signer = await ethers.getSigner( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6' + ); + const tx = await OperatorFilterRegistryContract.connect(signer).register( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6' + ); + const MockMarketPlace1CodeHash = + await OperatorFilterRegistryContract.connect(signer).codeHashOf( + MockERC1155MarketPlace1.address + ); + const MockMarketPlace2CodeHash = + await OperatorFilterRegistryContract.connect(signer).codeHashOf( + MockERC1155MarketPlace2.address + ); + await tx.wait(); + const tx2 = await OperatorFilterRegistryContract.connect( + signer + ).updateOperators( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6', + [MockERC1155MarketPlace1.address, MockERC1155MarketPlace2.address], + true + ); + await tx2.wait(); + const tx3 = await OperatorFilterRegistryContract.connect( + signer + ).updateCodeHashes( + '0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6', + [MockMarketPlace1CodeHash, MockMarketPlace2CodeHash], + true + ); + await tx3.wait(); + await network.provider.request({ + method: 'hardhat_stopImpersonatingAccount', + params: ['0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6'], + }); + + await deployments.fixture('Catalyst'); + + const OperatorFilterSubscription = await deployments.get( + 'OperatorFilterSubscription' + ); + const OperatorFilterSubscriptionContract = await ethers.getContractAt( + OperatorFilterSubscription.abi, + OperatorFilterSubscription.address + ); + const Catalyst = await deployments.get('Catalyst'); + const CatalystContract = await ethers.getContractAt( + Catalyst.abi, + Catalyst.address + ); + + const RoyaltyManager = await deployments.get('RoyaltyManager'); + const RoyaltyManagerContract = await ethers.getContractAt( + RoyaltyManager.abi, + RoyaltyManager.address + ); + const TRUSTED_FORWARDER_Data = await deployments.get( + 'TRUSTED_FORWARDER_V2' + ); + const TRUSTED_FORWARDER = await ethers.getContractAt( + TRUSTED_FORWARDER_Data.abi, + TRUSTED_FORWARDER_Data.address + ); + + return { + CatalystContract, + OperatorFilterSubscriptionContract, + RoyaltyManagerContract, + catalystAdmin, + TRUSTED_FORWARDER, + OPERATOR_FILTER_REGISTRY, + OperatorFilterRegistryContract, + catalystMinter, + MockERC1155MarketPlace1, + MockERC1155MarketPlace2, + MockERC1155MarketPlace3, + MockERC1155MarketPlace4, + }; + } +); + +describe('Catalyst', function () { + describe('check roles', function () { + it('admin', async function () { + const {CatalystContract, catalystAdmin} = await setupTest(); + const defaultAdminRole = await CatalystContract.DEFAULT_ADMIN_ROLE(); + expect( + await CatalystContract.hasRole(defaultAdminRole, catalystAdmin) + ).to.be.equals(true); + }); + it('minter', async function () { + const {CatalystContract, catalystMinter} = await setupTest(); + const minterRole = await CatalystContract.MINTER_ROLE(); + expect( + await CatalystContract.hasRole(minterRole, catalystMinter) + ).to.be.equals(true); + }); + }); + describe('Check Royalty', function () { + it('RoyaltyManager contract is set correctly', async function () { + const {CatalystContract, RoyaltyManagerContract} = await setupTest(); + expect(await CatalystContract.getRoyaltyManager()).to.be.equal( + RoyaltyManagerContract.address + ); + }); + it('Contract is registered on RoyaltyManager', async function () { + const {CatalystContract, RoyaltyManagerContract} = await setupTest(); + expect( + await RoyaltyManagerContract.getContractRoyalty( + CatalystContract.address + ) + ).to.be.equal(royaltyAmount); + }); + }); + describe('Operator Filter Registry', function () { + it('catalyst contract is registered correctly', async function () { + const {OperatorFilterRegistryContract, CatalystContract} = + await setupTest(); + expect( + await OperatorFilterRegistryContract.isRegistered( + CatalystContract.address + ) + ).to.be.true; + }); + it('catalyst contract is subscribed to correct address', async function () { + const { + OperatorFilterRegistryContract, + CatalystContract, + OperatorFilterSubscriptionContract, + } = await setupTest(); + expect( + await OperatorFilterRegistryContract.subscriptionOf( + CatalystContract.address + ) + ).to.be.equal(OperatorFilterSubscriptionContract.address); + }); + it('catalyst contract has correct market places black listed', async function () { + const { + OperatorFilterRegistryContract, + CatalystContract, + MockERC1155MarketPlace1, + MockERC1155MarketPlace2, + MockERC1155MarketPlace3, + MockERC1155MarketPlace4, + } = await setupTest(); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace1.address + ) + ).to.be.equal(true); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace2.address + ) + ).to.be.equal(true); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace3.address + ) + ).to.be.equal(false); + expect( + await OperatorFilterRegistryContract.isOperatorFiltered( + CatalystContract.address, + MockERC1155MarketPlace4.address + ) + ).to.be.equal(false); + }); + }); + describe('Trusted Forwarder', function () { + it('Trusted forwarder address is set correctly', async function () { + const {CatalystContract, TRUSTED_FORWARDER} = await setupTest(); + expect(await CatalystContract.getTrustedForwarder()).to.be.equal( + TRUSTED_FORWARDER.address + ); + }); + }); +}); diff --git a/packages/deploy/utils/abi.ts b/packages/deploy/utils/abi.ts new file mode 100644 index 0000000000..0964231db9 --- /dev/null +++ b/packages/deploy/utils/abi.ts @@ -0,0 +1,397 @@ +export const OperatorFilterRegistry_ABI = [ + { + inputs: [{internalType: 'address', name: 'operator', type: 'address'}], + name: 'AddressAlreadyFiltered', + type: 'error', + }, + { + inputs: [{internalType: 'address', name: 'filtered', type: 'address'}], + name: 'AddressFiltered', + type: 'error', + }, + { + inputs: [{internalType: 'address', name: 'operator', type: 'address'}], + name: 'AddressNotFiltered', + type: 'error', + }, + {inputs: [], name: 'AlreadyRegistered', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'subscription', type: 'address'}], + name: 'AlreadySubscribed', + type: 'error', + }, + {inputs: [], name: 'CannotCopyFromSelf', type: 'error'}, + {inputs: [], name: 'CannotFilterEOAs', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'CannotSubscribeToRegistrantWithSubscription', + type: 'error', + }, + {inputs: [], name: 'CannotSubscribeToSelf', type: 'error'}, + {inputs: [], name: 'CannotSubscribeToZeroAddress', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'subscription', type: 'address'}], + name: 'CannotUpdateWhileSubscribed', + type: 'error', + }, + { + inputs: [{internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}], + name: 'CodeHashAlreadyFiltered', + type: 'error', + }, + { + inputs: [ + {internalType: 'address', name: 'account', type: 'address'}, + {internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}, + ], + name: 'CodeHashFiltered', + type: 'error', + }, + { + inputs: [{internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}], + name: 'CodeHashNotFiltered', + type: 'error', + }, + {inputs: [], name: 'NotOwnable', type: 'error'}, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'NotRegistered', + type: 'error', + }, + {inputs: [], name: 'NotSubscribed', type: 'error'}, + {inputs: [], name: 'OnlyAddressOrOwner', type: 'error'}, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'codeHash', + type: 'bytes32', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'CodeHashUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: false, + internalType: 'bytes32[]', + name: 'codeHashes', + type: 'bytes32[]', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'CodeHashesUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'operator', + type: 'address', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'OperatorUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: false, + internalType: 'address[]', + name: 'operators', + type: 'address[]', + }, + {indexed: true, internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'OperatorsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + {indexed: true, internalType: 'bool', name: 'registered', type: 'bool'}, + ], + name: 'RegistrationUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'registrant', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'subscription', + type: 'address', + }, + {indexed: true, internalType: 'bool', name: 'subscribed', type: 'bool'}, + ], + name: 'SubscriptionUpdated', + type: 'event', + }, + { + inputs: [{internalType: 'address', name: 'a', type: 'address'}], + name: 'codeHashOf', + outputs: [{internalType: 'bytes32', name: '', type: 'bytes32'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'registrantToCopy', type: 'address'}, + ], + name: 'copyEntriesOf', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'uint256', name: 'index', type: 'uint256'}, + ], + name: 'filteredCodeHashAt', + outputs: [{internalType: 'bytes32', name: '', type: 'bytes32'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'filteredCodeHashes', + outputs: [{internalType: 'bytes32[]', name: '', type: 'bytes32[]'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'uint256', name: 'index', type: 'uint256'}, + ], + name: 'filteredOperatorAt', + outputs: [{internalType: 'address', name: '', type: 'address'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'filteredOperators', + outputs: [{internalType: 'address[]', name: '', type: 'address[]'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}, + ], + name: 'isCodeHashFiltered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operatorWithCode', type: 'address'}, + ], + name: 'isCodeHashOfFiltered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operator', type: 'address'}, + ], + name: 'isOperatorAllowed', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operator', type: 'address'}, + ], + name: 'isOperatorFiltered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'isRegistered', + outputs: [{internalType: 'bool', name: '', type: 'bool'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'register', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'registrantToCopy', type: 'address'}, + ], + name: 'registerAndCopyEntries', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'subscription', type: 'address'}, + ], + name: 'registerAndSubscribe', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'newSubscription', type: 'address'}, + ], + name: 'subscribe', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'uint256', name: 'index', type: 'uint256'}, + ], + name: 'subscriberAt', + outputs: [{internalType: 'address', name: '', type: 'address'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'subscribers', + outputs: [{internalType: 'address[]', name: '', type: 'address[]'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'subscriptionOf', + outputs: [{internalType: 'address', name: 'subscription', type: 'address'}], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{internalType: 'address', name: 'registrant', type: 'address'}], + name: 'unregister', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bool', name: 'copyExistingEntries', type: 'bool'}, + ], + name: 'unsubscribe', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bytes32', name: 'codeHash', type: 'bytes32'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateCodeHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'bytes32[]', name: 'codeHashes', type: 'bytes32[]'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateCodeHashes', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address', name: 'operator', type: 'address'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + {internalType: 'address', name: 'registrant', type: 'address'}, + {internalType: 'address[]', name: 'operators', type: 'address[]'}, + {internalType: 'bool', name: 'filtered', type: 'bool'}, + ], + name: 'updateOperators', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +]; diff --git a/packages/deploy/utils/bytecodes.ts b/packages/deploy/utils/bytecodes.ts new file mode 100644 index 0000000000..c4cce30a24 --- /dev/null +++ b/packages/deploy/utils/bytecodes.ts @@ -0,0 +1,2 @@ +export const OperatorFilterRegistryBytecode = + '0x608060405234801561001057600080fd5b50600436106101985760003560e01c8063712fc00b116100e3578063b314d4141161008c578063c430880511610066578063c4308805146103d1578063c6171134146103e4578063e4aecb54146103f757600080fd5b8063b314d4141461035b578063bbd652c71461036e578063c3c5a5471461039657600080fd5b8063a14584c1116100bd578063a14584c114610314578063a2f367ab14610327578063a6529eb51461033a57600080fd5b8063712fc00b146102db5780637d3e3dbe146102ee578063a0af29031461030157600080fd5b80633f1cc5fa116101455780635745ae281161011f5780635745ae28146102855780635eae3173146102a55780636af0c315146102c857600080fd5b80633f1cc5fa1461024c5780634420e4861461025f57806355940e511461027257600080fd5b80632ec2c246116101765780632ec2c246146101ee57806334a0dc10146102015780633c5030bb1461021457600080fd5b8063063298b61461019d5780631e06b4b4146101b257806322fa2762146101c5575b600080fd5b6101b06101ab366004613484565b61040a565b005b6101b06101c03660046134eb565b610854565b6101d86101d3366004613524565b610b57565b6040516101e59190613541565b60405180910390f35b6101b06101fc366004613524565b610bec565b6101b061020f366004613585565b610eaa565b610227610222366004613524565b611168565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e5565b61022761025a3660046135ba565b61121b565b6101b061026d366004613524565b6112bc565b6102276102803660046135ba565b6114b7565b610298610293366004613524565b6114e6565b6040516101e591906135e6565b6102b86102b33660046134eb565b611517565b60405190151581526020016101e5565b6102b86102d63660046135ba565b6115be565b6101b06102e9366004613634565b61164d565b6101b06102fc3660046134eb565b6119cd565b6101b061030f3660046134eb565b611da3565b6101b0610322366004613484565b612081565b6101b0610335366004613672565b61244f565b61034d6103483660046135ba565b6127b6565b6040519081526020016101e5565b6101b06103693660046134eb565b612845565b61034d61037c366004613524565b73ffffffffffffffffffffffffffffffffffffffff163f90565b6102b86103a4366004613524565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526002602052604090205416151590565b6102986103df366004613524565b612d63565b6102b86103f23660046134eb565b612df1565b6102b86104053660046134eb565b612f4c565b833373ffffffffffffffffffffffffffffffffffffffff821614610575578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156104ad575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526104aa918101906136b0565b60015b610524573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b606091505b50805160000361051c576040517fb2c1414000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b3373ffffffffffffffffffffffffffffffffffffffff821614610573576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80861660009081526002602052604090205416806105f1576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024015b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461066e576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260016020526040902084846107225760005b8181101561071c5760008888838181106106b8576106b86136cd565b90506020020135905060006106d68286612fdb90919063ffffffff16565b905080610712576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b505060010161069c565b506107f7565b60005b818110156107f5576000888883818110610741576107416136cd565b9050602002013590507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081036107a3576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107af8583612fe7565b9050806107eb576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018390526024016105e8565b5050600101610725565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f34e9f70c5a16a4df2a396cf0cbc4735eb3c7fb6ae40aaa0b34be7720121d1b9689896040516108429291906136fc565b60405180910390a35050505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610976578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156108f7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526108f4918101906136b0565b60015b610925573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610974576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036109db576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610a52576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610acf576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680610b46576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b610b508585612ff3565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114610bbe5773ffffffffffffffffffffffffffffffffffffffff81166000908152600160205260409020610bb79061318d565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600160205260409020610bb79061318d565b803373ffffffffffffffffffffffffffffffffffffffff821614610d0e578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610c8f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610c8c918101906136b0565b60015b610cbd573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610d0c576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260409020541680610d85576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610e305773ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260409020610de7908461319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80841691908616907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff831660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055519091907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59908390a3505050565b813373ffffffffffffffffffffffffffffffffffffffff821614610fcc578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610f4d575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610f4a918101906136b0565b60015b610f7b573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614610fca576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611043576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110a8576040517f237e6c2800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206110d7908561319a565b5073ffffffffffffffffffffffffffffffffffffffff80851660008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001684179055519092841691907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a48215611162576111628482612ff3565b50505050565b73ffffffffffffffffffffffffffffffffffffffff80821660009081526002602052604090205416806111df576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b8173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611216575060005b919050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146112835773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b90846131bc565b9150506112b6565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b290846131bc565b9150505b92915050565b803373ffffffffffffffffffffffffffffffffffffffff8216146113de578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561135f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261135c918101906136b0565b60015b61138d573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146113dc576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff828116600090815260026020526040902054161561143d576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a35050565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120610bb790836131bc565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602052604090206060906112b69061318d565b73ffffffffffffffffffffffffffffffffffffffff82811660008181526002602052604081205490928085163f9291169081146115865773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061157d90836131c8565b925050506112b6565b73ffffffffffffffffffffffffffffffffffffffff851660009081526001602052604090206115b590836131c8565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff80831660008181526002602052604081205490921690811461161e5773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131c8565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131c8565b823373ffffffffffffffffffffffffffffffffffffffff82161461176f578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156116f0575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526116ed918101906136b0565b60015b61171e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461176d576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47083036117c8576040517ff575ead800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808516600090815260026020526040902054168061183f576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146118bc576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600160205260409020836119345760006118f28287612fdb565b90508061192e576040517f478730a8000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b5061197e565b60006119408287612fe7565b90508061197c576040517f186bea00000000000000000000000000000000000000000000000000000000008152600481018790526024016105e8565b505b831515858773ffffffffffffffffffffffffffffffffffffffff167fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d60405160405180910390a4505050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611aef578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a70575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611a6d918101906136b0565b60015b611a9e573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611aed576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611b4f576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611bb4576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680611c2b576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611ca8576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220611d0f90866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff8716907f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5990600090a360405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b813373ffffffffffffffffffffffffffffffffffffffff821614611ec5578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611e46575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252611e43918101906136b0565b60015b611e74573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614611ec3576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611f2a576040517f1acab6b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600090815260026020526040902054168015611f8a576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612001576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff851660008181526002602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905551600192917f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb5991a3610b508585612ff3565b833373ffffffffffffffffffffffffffffffffffffffff8216146121a3578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612124575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252612121918101906136b0565b60015b612152573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff8216146121a1576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff808616600090815260026020526040902054168061221a576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b8573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612297576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902084846123655760005b8181101561235f5760008888838181106122e1576122e16136cd565b90506020020160208101906122f69190613524565b90506000612304858361319a565b905080612355576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b50506001016122c5565b50612404565b60005b81811015612402576000888883818110612384576123846136cd565b90506020020160208101906123999190613524565b905060006123a785836131e0565b9050806123f8576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016105e8565b5050600101612368565b505b8415158873ffffffffffffffffffffffffffffffffffffffff167f02b85afdacb82d5512c6f05566b3018677ffcbd7e5f75e498bc64081131cbd6c898960405161084292919061374e565b823373ffffffffffffffffffffffffffffffffffffffff821614612571578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156124f2575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526124ef918101906136b0565b60015b612520573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff82161461256f576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80851660009081526002602052604090205416806125e8576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612665576040517f04af4d6900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85166000908152602081905260409020836126f257600061269b828761319a565b9050806126ec576040517f45525c0e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b50612751565b60006126fe82876131e0565b90508061274f576040517f0bb4423400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff871660048201526024016105e8565b505b8315158573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a60405160405180910390a4505050505050565b73ffffffffffffffffffffffffffffffffffffffff8083166000818152600260205260408120549092169081146128165773ffffffffffffffffffffffffffffffffffffffff8116600090815260016020526040902061127b90846131bc565b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604090206112b290846131bc565b813373ffffffffffffffffffffffffffffffffffffffff821614612967578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128e8575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526128e5918101906136b0565b60015b612916573d8080156104db576040519150601f19603f3d011682016040523d82523d6000602084013e6104e0565b3373ffffffffffffffffffffffffffffffffffffffff821614612965576040517ffcf5eff800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129cc576040517f347f118f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612a19576040517fb05574d300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612a90576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612b0d576040517f73a4164900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600260205260409020541680612b84576040517fbfc6c33700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612c01576040517f768e549c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016105e8565b8473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612cac5773ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260409020612c63908661319a565b5060405160009073ffffffffffffffffffffffffffffffffffffffff80851691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e8908490a45b73ffffffffffffffffffffffffffffffffffffffff858116600090815260026020908152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001694891694851790559282526003905220612d1390866131e0565b5060405160019073ffffffffffffffffffffffffffffffffffffffff80871691908816907e38c54977604f1a5c0a3604cbbecd0153c81e3131799ead95755e8bb5d5b9e890600090a45050505050565b73ffffffffffffffffffffffffffffffffffffffff80821660008181526002602052604090205460609216908114612dc35773ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260409020610bb79061318d565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600260205260408120549091168015612f425773ffffffffffffffffffffffffffffffffffffffff81166000908152602081815260408083206001909252909120612e598286613202565b15612ea8576040517fa8cf495d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff861660048201526024016105e8565b73ffffffffffffffffffffffffffffffffffffffff85163b15612f3f5773ffffffffffffffffffffffffffffffffffffffff85163f612ee782826131c8565b15612f3d576040517f5f3853a900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87166004820152602481018290526044016105e8565b505b50505b5060019392505050565b73ffffffffffffffffffffffffffffffffffffffff808316600081815260026020526040812054909216908114612fac5773ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902061127b9084613202565b73ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090206112b29084613202565b6000610bb78383613231565b6000610bb78383613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526020818152604080832060019092528220909161302b83613373565b9050600061303883613373565b905060005b828110156130e057600061305186836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526020819052604081209192509061308490836131e0565b905080156130d65760405160019073ffffffffffffffffffffffffffffffffffffffff80851691908c16907f2738289d9deecdc30eb8ffc42876633caecca1ffa166e4efa89f408e17373a1a90600090a45b505060010161303d565b5060005b818110156131845760006130f885836131bc565b73ffffffffffffffffffffffffffffffffffffffff891660009081526001602052604081209192509061312b9083612fe7565b9050801561317a57604051600190839073ffffffffffffffffffffffffffffffffffffffff8c16907fb8036058bafea884aabc446ca15619fd86f5464a4ad96f64164ad6f77444354d90600090a45b50506001016130e4565b50505050505050565b60606000610bb78361337d565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613231565b6000610bb783836133d9565b60008181526001830160205260408120541515610bb7565b6000610bb78373ffffffffffffffffffffffffffffffffffffffff8416613324565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610bb7565b6000818152600183016020526040812054801561331a5760006132556001836137a9565b8554909150600090613269906001906137a9565b90508181146132ce576000866000018281548110613289576132896136cd565b90600052602060002001549050808760000184815481106132ac576132ac6136cd565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806132df576132df6137e3565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506112b6565b60009150506112b6565b600081815260018301602052604081205461336b575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556112b6565b5060006112b6565b60006112b6825490565b6060816000018054806020026020016040519081016040528092919081815260200182805480156133cd57602002820191906000526020600020905b8154815260200190600101908083116133b9575b50505050509050919050565b60008260000182815481106133f0576133f06136cd565b9060005260206000200154905092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461342557600080fd5b50565b60008083601f84011261343a57600080fd5b50813567ffffffffffffffff81111561345257600080fd5b6020830191508360208260051b850101111561346d57600080fd5b9250929050565b8035801515811461121657600080fd5b6000806000806060858703121561349a57600080fd5b84356134a581613403565b9350602085013567ffffffffffffffff8111156134c157600080fd5b6134cd87828801613428565b90945092506134e0905060408601613474565b905092959194509250565b600080604083850312156134fe57600080fd5b823561350981613403565b9150602083013561351981613403565b809150509250929050565b60006020828403121561353657600080fd5b8135610bb781613403565b6020808252825182820181905260009190848201906040850190845b818110156135795783518352928401929184019160010161355d565b50909695505050505050565b6000806040838503121561359857600080fd5b82356135a381613403565b91506135b160208401613474565b90509250929050565b600080604083850312156135cd57600080fd5b82356135d881613403565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561357957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101613602565b60008060006060848603121561364957600080fd5b833561365481613403565b92506020840135915061366960408501613474565b90509250925092565b60008060006060848603121561368757600080fd5b833561369281613403565b925060208401356136a281613403565b915061366960408501613474565b6000602082840312156136c257600080fd5b8151610bb781613403565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561373557600080fd5b8260051b80856040850137919091016040019392505050565b60208082528181018390526000908460408401835b8681101561379e57823561377681613403565b73ffffffffffffffffffffffffffffffffffffffff1682529183019190830190600101613763565b509695505050505050565b818103818111156112b6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220d2eb4529f96412ccc09b0c0c04d7ff105932b0b691aea14b7aa158442949a08664736f6c63430008110033'; diff --git a/yarn.lock b/yarn.lock index dd48097446..336d4c0ce8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,12 +42,12 @@ __metadata: linkType: hard "@aws-sdk/types@npm:^3.1.0": - version: 3.398.0 - resolution: "@aws-sdk/types@npm:3.398.0" + version: 3.418.0 + resolution: "@aws-sdk/types@npm:3.418.0" dependencies: - "@smithy/types": ^2.2.2 + "@smithy/types": ^2.3.3 tslib: ^2.5.0 - checksum: b0c3531336e3dc0a3e2524199026a2366a29a4eee07195bffd6a9d48c778924183ac9894029b1053d0f744121cec3b7d397828f2065acf37eea79d3106af1273 + checksum: b3e7526538a95b36d69498a8d807b8d1494a2f21190052a322096d3c555998b5b1fefc573ce7707badaa7540b84ff7c961ef01fe33e1c2bc6e3df7c24c780eb8 languageName: node linkType: hard @@ -70,30 +70,35 @@ __metadata: linkType: hard "@babel/code-frame@npm:^7.0.0": + version: 7.22.13 + resolution: "@babel/code-frame@npm:7.22.13" version: 7.22.13 resolution: "@babel/code-frame@npm:7.22.13" dependencies: "@babel/highlight": ^7.22.13 chalk: ^2.4.2 + checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058 + "@babel/highlight": ^7.22.13 + chalk: ^2.4.2 checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-validator-identifier@npm:7.22.5" - checksum: 7f0f30113474a28298c12161763b49de5018732290ca4de13cdaefd4fd0d635a6fe3f6686c37a02905fb1e64f21a5ee2b55140cf7b070e729f1bd66866506aea +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc languageName: node linkType: hard "@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.22.13": - version: 7.22.13 - resolution: "@babel/highlight@npm:7.22.13" + version: 7.22.20 + resolution: "@babel/highlight@npm:7.22.20" dependencies: - "@babel/helper-validator-identifier": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.20 chalk: ^2.4.2 js-tokens: ^4.0.0 - checksum: 7266d2bff8aa8fc78eb65b6e92a8211e12897a731126a282d2f9bb50d8fcaa4c1b02af2284f990ac7e3ab8d892d448a2cab8f5ed0ea8a90bce2c025b11ebe802 + checksum: 84bd034dca309a5e680083cd827a766780ca63cef37308404f17653d32366ea76262bd2364b2d38776232f2d01b649f26721417d507e8b4b6da3e4e739f6d134 languageName: node linkType: hard @@ -214,9 +219,9 @@ __metadata: linkType: hard "@eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.6.1": - version: 4.8.0 - resolution: "@eslint-community/regexpp@npm:4.8.0" - checksum: 601e6d033d556e98e8c929905bef335f20d7389762812df4d0f709d9b4d2631610dda975fb272e23b5b68e24a163b3851b114c8080a0a19fb4c141a1eff6305b + version: 4.9.1 + resolution: "@eslint-community/regexpp@npm:4.9.1" + checksum: 06fb839e9c756f6375cc545c2f2e05a0a64576bd6370e8e3c07983fd29a3d6e164ef4aa48a361f7d27e6713ab79c83053ff6a2ccb78748bc955e344279c4a3b6 languageName: node linkType: hard @@ -237,6 +242,9 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^2.1.2": + version: 2.1.2 + resolution: "@eslint/eslintrc@npm:2.1.2" "@eslint/eslintrc@npm:^2.1.2": version: 2.1.2 resolution: "@eslint/eslintrc@npm:2.1.2" @@ -251,13 +259,14 @@ __metadata: minimatch: ^3.1.2 strip-json-comments: ^3.1.1 checksum: bc742a1e3b361f06fedb4afb6bf32cbd27171292ef7924f61c62f2aed73048367bcc7ac68f98c06d4245cd3fabc43270f844e3c1699936d4734b3ac5398814a7 + checksum: bc742a1e3b361f06fedb4afb6bf32cbd27171292ef7924f61c62f2aed73048367bcc7ac68f98c06d4245cd3fabc43270f844e3c1699936d4734b3ac5398814a7 languageName: node linkType: hard -"@eslint/js@npm:8.48.0": - version: 8.48.0 - resolution: "@eslint/js@npm:8.48.0" - checksum: b2755f9c0ee810c886eba3c50dcacb184ba5a5cd1cbc01988ee506ad7340653cae0bd55f1d95c64b56dfc6d25c2caa7825335ffd2c50165bae9996fe0f396851 +"@eslint/js@npm:8.50.0": + version: 8.50.0 + resolution: "@eslint/js@npm:8.50.0" + checksum: 302478f2acaaa7228729ec6a04f56641590185e1d8cd1c836a6db8a6b8009f80a57349341be9fbb9aa1721a7a569d1be3ffc598a33300d22816f11832095386c languageName: node linkType: hard @@ -292,6 +301,15 @@ __metadata: languageName: node linkType: hard +"@ethereumjs/rlp@npm:^4.0.1": + version: 4.0.1 + resolution: "@ethereumjs/rlp@npm:4.0.1" + bin: + rlp: bin/rlp + checksum: 30db19c78faa2b6ff27275ab767646929207bb207f903f09eb3e4c273ce2738b45f3c82169ddacd67468b4f063d8d96035f2bf36f02b6b7e4d928eefe2e3ecbc + languageName: node + linkType: hard + "@ethereumjs/tx@npm:^3.3.2, @ethereumjs/tx@npm:^3.5.2": version: 3.5.2 resolution: "@ethereumjs/tx@npm:3.5.2" @@ -313,7 +331,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/abi@npm:5.7.0, @ethersproject/abi@npm:^5.0.0-beta.146, @ethersproject/abi@npm:^5.0.9, @ethersproject/abi@npm:^5.1.2, @ethersproject/abi@npm:^5.4.0, @ethersproject/abi@npm:^5.7.0": +"@ethersproject/abi@npm:5.7.0, @ethersproject/abi@npm:^5.0.9, @ethersproject/abi@npm:^5.1.2, @ethersproject/abi@npm:^5.4.0, @ethersproject/abi@npm:^5.6.3, @ethersproject/abi@npm:^5.7.0": version: 5.7.0 resolution: "@ethersproject/abi@npm:5.7.0" dependencies: @@ -715,6 +733,13 @@ __metadata: languageName: node linkType: hard +"@fastify/busboy@npm:^2.0.0": + version: 2.0.0 + resolution: "@fastify/busboy@npm:2.0.0" + checksum: 41879937ce1dee6421ef9cd4da53239830617e1f0bb7a0e843940772cd72827205d05e518af6adabe6e1ea19301285fff432b9d11bad01a531e698bea95c781b + languageName: node + linkType: hard + "@graphql-typed-document-node/core@npm:^3.1.0": version: 3.2.0 resolution: "@graphql-typed-document-node/core@npm:3.2.0" @@ -724,14 +749,14 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.10": - version: 0.11.10 - resolution: "@humanwhocodes/config-array@npm:0.11.10" +"@humanwhocodes/config-array@npm:^0.11.11": + version: 0.11.11 + resolution: "@humanwhocodes/config-array@npm:0.11.11" dependencies: "@humanwhocodes/object-schema": ^1.2.1 debug: ^4.1.1 minimatch: ^3.0.5 - checksum: 1b1302e2403d0e35bc43e66d67a2b36b0ad1119efc704b5faff68c41f791a052355b010fb2d27ef022670f550de24cd6d08d5ecf0821c16326b7dcd0ee5d5d8a + checksum: db84507375ab77b8ffdd24f498a5b49ad6b64391d30dd2ac56885501d03964d29637e05b1ed5aefa09d57ac667e28028bc22d2da872bfcd619652fbdb5f4ca19 languageName: node linkType: hard @@ -767,6 +792,13 @@ __metadata: languageName: node linkType: hard +"@iarna/toml@npm:2.2.5": + version: 2.2.5 + resolution: "@iarna/toml@npm:2.2.5" + checksum: b63b2b2c4fd67969a6291543ada0303d45593801ee744b60f5390f183c03d9192bc67a217abb24be945158f1935f02840d9ffff40c0142aa171b5d3b6b6a3ea5 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -812,6 +844,27 @@ __metadata: languageName: node linkType: hard +"@manifoldxyz/libraries-solidity@npm:^1.0.4": + version: 1.0.4 + resolution: "@manifoldxyz/libraries-solidity@npm:1.0.4" + dependencies: + "@openzeppelin/contracts": 4.7.3 + "@openzeppelin/contracts-upgradeable": 4.7.3 + checksum: fdc8c5cbbc004aa40ee8ab819b66d4880ea2fd641b18b7cc487cefea0173060f1451c9203961cc83a007893900c9afd5d1fb6e531c7e38e8eed44bea52e22d43 + languageName: node + linkType: hard + +"@manifoldxyz/royalty-registry-solidity@npm:^2.0.3": + version: 2.0.3 + resolution: "@manifoldxyz/royalty-registry-solidity@npm:2.0.3" + dependencies: + "@manifoldxyz/libraries-solidity": ^1.0.4 + "@openzeppelin/contracts": ^4.8.0 + "@openzeppelin/contracts-upgradeable": ^4.8.0 + checksum: a44111cb7f8baacf00cbe9d2290680622d97c4188c2b9d95e11b6372da8e3740a2b2a75abbb226df272ac2a76b2ec6420cf9d408f42c768840645964d018fe9d + languageName: node + linkType: hard + "@maticnetwork/fx-portal@npm:^1.0.5": version: 1.0.5 resolution: "@maticnetwork/fx-portal@npm:1.0.5" @@ -843,6 +896,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:1.1.0, @noble/curves@npm:~1.1.0": + version: 1.1.0 + resolution: "@noble/curves@npm:1.1.0" + dependencies: + "@noble/hashes": 1.3.1 + checksum: 2658cdd3f84f71079b4e3516c47559d22cf4b55c23ac8ee9d2b1f8e5b72916d9689e59820e0f9d9cb4a46a8423af5b56dc6bb7782405c88be06a015180508db5 + languageName: node + linkType: hard + "@noble/hashes@npm:1.1.2": version: 1.1.2 resolution: "@noble/hashes@npm:1.1.2" @@ -871,6 +933,20 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.3.1": + version: 1.3.1 + resolution: "@noble/hashes@npm:1.3.1" + checksum: 7fdefc0f7a0c1ec27acc6ff88841793e3f93ec4ce6b8a6a12bfc0dd70ae6b7c4c82fe305fdfeda1735d5ad4a9eebe761e6693b3d355689c559e91242f4bc95b1 + languageName: node + linkType: hard + +"@noble/hashes@npm:~1.3.0, @noble/hashes@npm:~1.3.1": + version: 1.3.2 + resolution: "@noble/hashes@npm:1.3.2" + checksum: fe23536b436539d13f90e4b9be843cc63b1b17666a07634a2b1259dded6f490be3d050249e6af98076ea8f2ea0d56f578773c2197f2aa0eeaa5fba5bc18ba474 + languageName: node + linkType: hard + "@noble/secp256k1@npm:1.7.1, @noble/secp256k1@npm:~1.7.0": version: 1.7.1 resolution: "@noble/secp256k1@npm:1.7.1" @@ -935,6 +1011,21 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-block@npm:5.0.2": + version: 5.0.2 + resolution: "@nomicfoundation/ethereumjs-block@npm:5.0.2" + 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 + checksum: 7ff744f44a01f1c059ca7812a1cfc8089f87aa506af6cb39c78331dca71b32993cbd6fa05ad03f8c4f4fab73bb998a927af69e0d8ff01ae192ee5931606e09f5 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-blockchain@npm:7.0.1": version: 7.0.1 resolution: "@nomicfoundation/ethereumjs-blockchain@npm:7.0.1" @@ -977,6 +1068,27 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-blockchain@npm:7.0.2": + version: 7.0.2 + resolution: "@nomicfoundation/ethereumjs-blockchain@npm:7.0.2" + 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 + checksum: b7e440dcd73e32aa72d13bfd28cb472773c9c60ea808a884131bf7eb3f42286ad594a0864215f599332d800f3fe1f772fff4b138d2dcaa8f41e4d8389bff33e7 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-common@npm:4.0.1": version: 4.0.1 resolution: "@nomicfoundation/ethereumjs-common@npm:4.0.1" @@ -997,6 +1109,16 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-common@npm:4.0.2": + version: 4.0.2 + resolution: "@nomicfoundation/ethereumjs-common@npm:4.0.2" + dependencies: + "@nomicfoundation/ethereumjs-util": 9.0.2 + crc-32: ^1.2.0 + checksum: f0d84704d6254d374299c19884312bd5666974b4b6f342d3f10bc76e549de78d20e45a53d25fbdc146268a52335497127e4f069126da7c60ac933a158e704887 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-ethash@npm:3.0.1": version: 3.0.1 resolution: "@nomicfoundation/ethereumjs-ethash@npm:3.0.1" @@ -1025,6 +1147,20 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-ethash@npm:3.0.2": + version: 3.0.2 + resolution: "@nomicfoundation/ethereumjs-ethash@npm:3.0.2" + 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 + checksum: e4011e4019dd9b92f7eeebfc1e6c9a9685c52d8fd0ee4f28f03e50048a23b600c714490827f59fdce497b3afb503b3fd2ebf6815ff307e9949c3efeff1403278 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-evm@npm:2.0.1": version: 2.0.1 resolution: "@nomicfoundation/ethereumjs-evm@npm:2.0.1" @@ -1057,6 +1193,22 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-evm@npm:2.0.2": + version: 2.0.2 + resolution: "@nomicfoundation/ethereumjs-evm@npm:2.0.2" + 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 + checksum: a23cf570836ddc147606b02df568069de946108e640f902358fef67e589f6b371d856056ee44299d9b4e3497f8ae25faa45e6b18fefd90e9b222dc6a761d85f0 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-rlp@npm:5.0.1": version: 5.0.1 resolution: "@nomicfoundation/ethereumjs-rlp@npm:5.0.1" @@ -1075,6 +1227,15 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-rlp@npm:5.0.2": + version: 5.0.2 + resolution: "@nomicfoundation/ethereumjs-rlp@npm:5.0.2" + bin: + rlp: bin/rlp + checksum: a74434cadefca9aa8754607cc1ad7bb4bbea4ee61c6214918e60a5bbee83206850346eb64e39fd1fe97f854c7ec0163e01148c0c881dda23881938f0645a0ef2 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-statemanager@npm:2.0.1": version: 2.0.1 resolution: "@nomicfoundation/ethereumjs-statemanager@npm:2.0.1" @@ -1103,6 +1264,20 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-statemanager@npm:2.0.2": + version: 2.0.2 + resolution: "@nomicfoundation/ethereumjs-statemanager@npm:2.0.2" + 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 + checksum: 3ab6578e252e53609afd98d8ba42a99f182dcf80252f23ed9a5e0471023ffb2502130f85fc47fa7c94cd149f9be799ed9a0942ca52a143405be9267f4ad94e64 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-trie@npm:6.0.1": version: 6.0.1 resolution: "@nomicfoundation/ethereumjs-trie@npm:6.0.1" @@ -1129,6 +1304,19 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-trie@npm:6.0.2": + version: 6.0.2 + resolution: "@nomicfoundation/ethereumjs-trie@npm:6.0.2" + 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 + checksum: d4da918d333851b9f2cce7dbd25ab5753e0accd43d562d98fd991b168b6a08d1794528f0ade40fe5617c84900378376fe6256cdbe52c8d66bf4c53293bbc7c40 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-tx@npm:5.0.1": version: 5.0.1 resolution: "@nomicfoundation/ethereumjs-tx@npm:5.0.1" @@ -1157,6 +1345,20 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-tx@npm:5.0.2": + version: 5.0.2 + resolution: "@nomicfoundation/ethereumjs-tx@npm:5.0.2" + 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 + checksum: 0bbcea75786b2ccb559afe2ecc9866fb4566a9f157b6ffba4f50960d14f4b3da2e86e273f6fadda9b860e67cfcabf589970fb951b328cb5f900a585cd21842a2 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-util@npm:9.0.1": version: 9.0.1 resolution: "@nomicfoundation/ethereumjs-util@npm:9.0.1" @@ -1179,6 +1381,17 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-util@npm:9.0.2": + version: 9.0.2 + resolution: "@nomicfoundation/ethereumjs-util@npm:9.0.2" + dependencies: + "@chainsafe/ssz": ^0.10.0 + "@nomicfoundation/ethereumjs-rlp": 5.0.2 + ethereum-cryptography: 0.1.3 + checksum: 3a08f7b88079ef9f53b43da9bdcb8195498fd3d3911c2feee2571f4d1204656053f058b2f650471c86f7d2d0ba2f814768c7cfb0f266eede41c848356afc4900 + languageName: node + linkType: hard + "@nomicfoundation/ethereumjs-vm@npm:7.0.1": version: 7.0.1 resolution: "@nomicfoundation/ethereumjs-vm@npm:7.0.1" @@ -1221,6 +1434,27 @@ __metadata: languageName: node linkType: hard +"@nomicfoundation/ethereumjs-vm@npm:7.0.2": + version: 7.0.2 + resolution: "@nomicfoundation/ethereumjs-vm@npm:7.0.2" + 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 + checksum: 1c25ba4d0644cadb8a2b0241a4bb02e578bfd7f70e3492b855c2ab5c120cb159cb8f7486f84dc1597884bd1697feedbfb5feb66e91352afb51f3694fd8e4a043 + languageName: node + linkType: hard + "@nomicfoundation/hardhat-chai-matchers@npm:1, @nomicfoundation/hardhat-chai-matchers@npm:^1.0.6": version: 1.0.6 resolution: "@nomicfoundation/hardhat-chai-matchers@npm:1.0.6" @@ -1240,6 +1474,8 @@ __metadata: linkType: hard "@nomicfoundation/hardhat-chai-matchers@npm:^2.0.1": + version: 2.0.2 + resolution: "@nomicfoundation/hardhat-chai-matchers@npm:2.0.2" version: 2.0.2 resolution: "@nomicfoundation/hardhat-chai-matchers@npm:2.0.2" dependencies: @@ -1253,6 +1489,7 @@ __metadata: ethers: ^6.1.0 hardhat: ^2.9.4 checksum: 62d7d69f6b34a06bc43fe0dab8adc9e3b6f907f1b68bb5cf47feb78a4c7ef057b9a4aa713611abeca38df9d8fe166bbd9bbf98e42c4edbdf7aece477b3f9485a + checksum: 62d7d69f6b34a06bc43fe0dab8adc9e3b6f907f1b68bb5cf47feb78a4c7ef057b9a4aa713611abeca38df9d8fe166bbd9bbf98e42c4edbdf7aece477b3f9485a languageName: node linkType: hard @@ -1269,7 +1506,7 @@ __metadata: languageName: node linkType: hard -"@nomicfoundation/hardhat-network-helpers@npm:^1.0.8": +"@nomicfoundation/hardhat-network-helpers@npm:^1.0.0, @nomicfoundation/hardhat-network-helpers@npm:^1.0.8": version: 1.0.9 resolution: "@nomicfoundation/hardhat-network-helpers@npm:1.0.9" dependencies: @@ -1277,6 +1514,7 @@ __metadata: peerDependencies: hardhat: ^2.9.5 checksum: ff378795075af853aeaacb7bc0783928d947d7f9fb043c046fcaffdf1e1219c4af47b18ea7fa2c10fe0b25daef48f13ae8b103bc11ea494ecdfbe34a3dcdf936 + checksum: ff378795075af853aeaacb7bc0783928d947d7f9fb043c046fcaffdf1e1219c4af47b18ea7fa2c10fe0b25daef48f13ae8b103bc11ea494ecdfbe34a3dcdf936 languageName: node linkType: hard @@ -1333,6 +1571,8 @@ __metadata: linkType: hard "@nomicfoundation/hardhat-verify@npm:^1.0.0": + version: 1.1.1 + resolution: "@nomicfoundation/hardhat-verify@npm:1.1.1" version: 1.1.1 resolution: "@nomicfoundation/hardhat-verify@npm:1.1.1" dependencies: @@ -1348,6 +1588,7 @@ __metadata: peerDependencies: hardhat: ^2.0.4 checksum: 2d83d32d6833f23fb62c30c68c9a2ab3956098030edcf459e69639960f059c72572d203bcf92f191c69c9cb0fbbf011a1113bacde1e3cbb28d5e812334f04f32 + checksum: 2d83d32d6833f23fb62c30c68c9a2ab3956098030edcf459e69639960f059c72572d203bcf92f191c69c9cb0fbbf011a1113bacde1e3cbb28d5e812334f04f32 languageName: node linkType: hard @@ -1480,6 +1721,16 @@ __metadata: languageName: node linkType: hard +"@nomiclabs/hardhat-ethers@npm:hardhat-deploy-ethers@^0.3.0-beta.13": + version: 0.3.0-beta.13 + resolution: "hardhat-deploy-ethers@npm:0.3.0-beta.13" + peerDependencies: + ethers: ^5.0.0 + hardhat: ^2.0.0 + checksum: 45206bf8d088cda08822ecf79d73e4027d8a4777cc23c3ef94568e316c45b8597130d72826fb2417edd32fe4b3dc54097161bef577663769b5c47b8262b983bb + languageName: node + linkType: hard + "@nomiclabs/hardhat-etherscan@npm:^3.0.3, @nomiclabs/hardhat-etherscan@npm:^3.1.7": version: 3.1.7 resolution: "@nomiclabs/hardhat-etherscan@npm:3.1.7" @@ -1637,9 +1888,9 @@ __metadata: linkType: hard "@octokit/openapi-types@npm:^18.0.0": - version: 18.0.0 - resolution: "@octokit/openapi-types@npm:18.0.0" - checksum: d487d6c6c1965e583eee417d567e4fe3357a98953fc49bce1a88487e7908e9b5dbb3e98f60dfa340e23b1792725fbc006295aea071c5667a813b9c098185b56f + version: 18.1.1 + resolution: "@octokit/openapi-types@npm:18.1.1" + checksum: 94f42977fd2fcb9983c781fd199bc11218885a1226d492680bfb1268524a1b2af48a768eef90c63b80a2874437de641d59b3b7f640a5afa93e7c21fe1a79069a languageName: node linkType: hard @@ -1772,13 +2023,27 @@ __metadata: languageName: node linkType: hard -"@openzeppelin/contracts-upgradeable@npm:^4.8.2, @openzeppelin/contracts-upgradeable@npm:^4.9.0, @openzeppelin/contracts-upgradeable@npm:^4.9.2": +"@openzeppelin/contracts-upgradeable@npm:4.7.3": + version: 4.7.3 + resolution: "@openzeppelin/contracts-upgradeable@npm:4.7.3" + checksum: c9ffb40cb847a975d440204fc6a811f43af960050242f707332b984d29bd16dc242ffa0935de61867aeb9e0357fadedb16b09b276deda5e9775582face831021 + languageName: node + linkType: hard + +"@openzeppelin/contracts-upgradeable@npm:^4.8.0, @openzeppelin/contracts-upgradeable@npm:^4.8.2, @openzeppelin/contracts-upgradeable@npm:^4.9.0, @openzeppelin/contracts-upgradeable@npm:^4.9.2": version: 4.9.3 resolution: "@openzeppelin/contracts-upgradeable@npm:4.9.3" checksum: bda0240b1d44c913ec5a4e109c622f216c2bbd7b468d210822f75782a5f7fe0609d08bf03b78b253333625e99e507cf2f75212f1de3b274bd9fc64ae967aeec3 languageName: node linkType: hard +"@openzeppelin/contracts@npm:4.7.3": + version: 4.7.3 + resolution: "@openzeppelin/contracts@npm:4.7.3" + checksum: 18382fcacf7cfd652f5dd0e70c08f08ea74eaa8ff11e9f9850639ada70198ae01a3f9493d89a52d724f2db394e9616bf6258017804612ba273167cf657fbb073 + languageName: node + linkType: hard + "@openzeppelin/contracts@npm:^3.2.1-solc-0.7": version: 3.4.2 resolution: "@openzeppelin/contracts@npm:3.4.2" @@ -1786,28 +2051,96 @@ __metadata: languageName: node linkType: hard -"@openzeppelin/contracts@npm:^4.2.0, @openzeppelin/contracts@npm:^4.7.3": +"@openzeppelin/contracts@npm:^4.2.0, @openzeppelin/contracts@npm:^4.7.3, @openzeppelin/contracts@npm:^4.8.0, @openzeppelin/contracts@npm:^4.9.0": version: 4.9.3 resolution: "@openzeppelin/contracts@npm:4.9.3" checksum: 4932063e733b35fa7669b9fe2053f69b062366c5c208b0c6cfa1ac451712100c78acff98120c3a4b88d94154c802be05d160d71f37e7d74cadbe150964458838 languageName: node linkType: hard -"@parcel/watcher@npm:2.0.4": - version: 2.0.4 - resolution: "@parcel/watcher@npm:2.0.4" +"@openzeppelin/defender-base-client@npm:^1.46.0": + version: 1.48.0 + resolution: "@openzeppelin/defender-base-client@npm:1.48.0" dependencies: - node-addon-api: ^3.2.1 - node-gyp: latest - node-gyp-build: ^4.3.0 - checksum: 890bdc69a52942791b276caa2cd65ef816576d6b5ada91aa28cf302b35d567c801dafe167f2525dcb313f5b420986ea11bd56228dd7ddde1116944d8f924a0a1 + amazon-cognito-identity-js: ^6.0.1 + async-retry: ^1.3.3 + axios: ^1.4.0 + lodash: ^4.17.19 + node-fetch: ^2.6.0 + checksum: 7391ac924b48d0ec38853f2d85aef837edbe7b8caf7afb32e6914e2a68ec40a0377bdd0cd60b52d35edaf6b4d7d57ebd4d34805adb410a9d5051f71d2c329455 languageName: node linkType: hard -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f +"@openzeppelin/hardhat-upgrades@npm:^1.28.0": + version: 1.28.0 + resolution: "@openzeppelin/hardhat-upgrades@npm:1.28.0" + dependencies: + "@openzeppelin/defender-base-client": ^1.46.0 + "@openzeppelin/platform-deploy-client": ^0.8.0 + "@openzeppelin/upgrades-core": ^1.27.0 + chalk: ^4.1.0 + debug: ^4.1.1 + proper-lockfile: ^4.1.1 + peerDependencies: + "@nomiclabs/hardhat-ethers": ^2.0.0 + "@nomiclabs/hardhat-etherscan": ^3.1.0 + ethers: ^5.0.5 + hardhat: ^2.0.2 + peerDependenciesMeta: + "@nomiclabs/harhdat-etherscan": + optional: true + bin: + migrate-oz-cli-project: dist/scripts/migrate-oz-cli-project.js + checksum: b37a5eb7c3a5c1fb4ae6754f5fe1d6e93eb6bc143861f57babf5c7d66706ee3e44ca7d57db17ce2ec6c7014f09c269d506f62b3b116897407fdb0d1ff68f4925 + languageName: node + linkType: hard + +"@openzeppelin/platform-deploy-client@npm:^0.8.0": + version: 0.8.0 + resolution: "@openzeppelin/platform-deploy-client@npm:0.8.0" + dependencies: + "@ethersproject/abi": ^5.6.3 + "@openzeppelin/defender-base-client": ^1.46.0 + axios: ^0.21.2 + lodash: ^4.17.19 + node-fetch: ^2.6.0 + checksum: 0ce050e185a812c366ceef7dcfce526815babab9396275d9724f324a548ddfdca92ea9913ce61356dcd8c014fc495890c8e21afab4a197e0e14e761c698cce68 + languageName: node + linkType: hard + +"@openzeppelin/upgrades-core@npm:^1.27.0": + version: 1.30.0 + resolution: "@openzeppelin/upgrades-core@npm:1.30.0" + dependencies: + cbor: ^9.0.0 + chalk: ^4.1.0 + compare-versions: ^6.0.0 + debug: ^4.1.1 + ethereumjs-util: ^7.0.3 + minimist: ^1.2.7 + proper-lockfile: ^4.1.1 + solidity-ast: ^0.4.51 + bin: + openzeppelin-upgrades-core: dist/cli/cli.js + checksum: bd4ae49ed868dd552c346f28518651ab6c9763cde29ab31c4dfbd2b6159e1ab9c6f5e84157e5a7f413863f833b4a5ccbd9f0458a02bd0ab79ab46e79e0dbf754 + languageName: node + linkType: hard + +"@parcel/watcher@npm:2.0.4": + version: 2.0.4 + resolution: "@parcel/watcher@npm:2.0.4" + dependencies: + node-addon-api: ^3.2.1 + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: 890bdc69a52942791b276caa2cd65ef816576d6b5ada91aa28cf302b35d567c801dafe167f2525dcb313f5b420986ea11bd56228dd7ddde1116944d8f924a0a1 + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 6ad6a00fc4f2f2cfc6bff76fb1d88b8ee20bc0601e18ebb01b6d4be583733a860239a521a7fbca73b612e66705078809483549d2b18f370eb346c5155c8e4a0f languageName: node linkType: hard @@ -1850,6 +2183,53 @@ __metadata: languageName: node linkType: hard +"@sandbox-smart-contracts/asset@*, @sandbox-smart-contracts/asset@workspace:packages/asset": + version: 0.0.0-use.local + resolution: "@sandbox-smart-contracts/asset@workspace:packages/asset" + dependencies: + "@ethersproject/abi": ^5.7.0 + "@ethersproject/providers": ^5.7.2 + "@manifoldxyz/libraries-solidity": ^1.0.4 + "@manifoldxyz/royalty-registry-solidity": ^2.0.3 + "@nomicfoundation/hardhat-chai-matchers": ^1.0.6 + "@nomicfoundation/hardhat-network-helpers": ^1.0.0 + "@nomicfoundation/hardhat-toolbox": ^2.0.2 + "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13" + "@nomiclabs/hardhat-etherscan": ^3.1.7 + "@openzeppelin/contracts": ^4.9.0 + "@openzeppelin/contracts-upgradeable": ^4.9.0 + "@openzeppelin/hardhat-upgrades": ^1.28.0 + "@sandbox-smart-contracts/dependency-metatx": "*" + "@sandbox-smart-contracts/dependency-operator-filter": "*" + "@sandbox-smart-contracts/dependency-royalty-management": "*" + "@typechain/ethers-v5": ^10.2.1 + "@typechain/hardhat": ^6.1.6 + "@types/chai": ^4.3.5 + "@types/mocha": ^10.0.1 + "@types/node": ^20.1.2 + "@typescript-eslint/eslint-plugin": ^5.59.8 + "@typescript-eslint/parser": ^5.59.8 + chai: ^4.3.7 + dotenv: ^16.1.4 + eslint: ^8.41.0 + eslint-config-prettier: ^8.8.0 + eslint-plugin-mocha: ^10.1.0 + eslint-plugin-prettier: ^4.2.1 + ethers: ^5.7.2 + hardhat: ^2.14.1 + hardhat-gas-reporter: ^1.0.9 + operator-filter-registry: ^1.4.2 + prettier: ^2.8.8 + prettier-plugin-solidity: 1.0.0-beta.11 + solhint: ^3.4.1 + solhint-plugin-prettier: ^0.0.5 + solidity-coverage: ^0.8.2 + ts-node: ^10.9.1 + typechain: ^8.1.1 + typescript: ^5.0.4 + languageName: unknown + linkType: soft + "@sandbox-smart-contracts/core@workspace:packages/core": version: 0.0.0-use.local resolution: "@sandbox-smart-contracts/core@workspace:packages/core" @@ -1911,6 +2291,7 @@ __metadata: prettier-plugin-solidity: 1.0.0-beta.11 readline: ^1.3.0 solhint: 3.4.1 + solhint: 3.4.1 solhint-plugin-prettier: ^0.0.5 solidity-coverage: 0.8.2 ts-node: ^10.9.1 @@ -1918,7 +2299,7 @@ __metadata: languageName: unknown linkType: soft -"@sandbox-smart-contracts/dependency-metatx@workspace:packages/dependency-metatx": +"@sandbox-smart-contracts/dependency-metatx@*, @sandbox-smart-contracts/dependency-metatx@workspace:packages/dependency-metatx": version: 0.0.0-use.local resolution: "@sandbox-smart-contracts/dependency-metatx@workspace:packages/dependency-metatx" dependencies: @@ -1958,6 +2339,93 @@ __metadata: languageName: unknown linkType: soft +"@sandbox-smart-contracts/dependency-operator-filter@*, @sandbox-smart-contracts/dependency-operator-filter@workspace:packages/dependency-operator-filter": + version: 0.0.0-use.local + resolution: "@sandbox-smart-contracts/dependency-operator-filter@workspace:packages/dependency-operator-filter" + dependencies: + "@ethersproject/abi": ^5.7.0 + "@ethersproject/providers": ^5.7.2 + "@nomicfoundation/hardhat-chai-matchers": ^1.0.6 + "@nomicfoundation/hardhat-network-helpers": ^1.0.0 + "@nomicfoundation/hardhat-toolbox": ^2.0.2 + "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13" + "@nomiclabs/hardhat-etherscan": ^3.1.7 + "@openzeppelin/contracts": ^4.9.0 + "@openzeppelin/contracts-upgradeable": ^4.9.0 + "@openzeppelin/hardhat-upgrades": ^1.28.0 + "@sandbox-smart-contracts/dependency-metatx": "*" + "@typechain/ethers-v5": ^10.2.1 + "@typechain/hardhat": ^6.1.6 + "@types/chai": ^4.3.5 + "@types/mocha": ^10.0.1 + "@types/node": ^20.1.2 + "@typescript-eslint/eslint-plugin": ^5.59.8 + "@typescript-eslint/parser": ^5.59.8 + chai: ^4.3.7 + dotenv: ^16.1.4 + eslint: ^8.41.0 + eslint-config-prettier: ^8.8.0 + eslint-plugin-mocha: ^10.1.0 + eslint-plugin-prettier: ^4.2.1 + ethers: ^5.7.2 + hardhat: ^2.14.1 + hardhat-gas-reporter: ^1.0.9 + operator-filter-registry: ^1.4.2 + prettier: ^2.8.8 + prettier-plugin-solidity: 1.0.0-beta.11 + solhint: ^3.4.1 + solhint-plugin-prettier: ^0.0.5 + solidity-coverage: ^0.8.2 + ts-node: ^10.9.1 + typechain: ^8.1.1 + typescript: ^5.0.4 + languageName: unknown + linkType: soft + +"@sandbox-smart-contracts/dependency-royalty-management@*, @sandbox-smart-contracts/dependency-royalty-management@workspace:packages/dependency-royalty-management": + version: 0.0.0-use.local + resolution: "@sandbox-smart-contracts/dependency-royalty-management@workspace:packages/dependency-royalty-management" + dependencies: + "@ethersproject/abi": ^5.7.0 + "@ethersproject/providers": ^5.7.2 + "@manifoldxyz/libraries-solidity": ^1.0.4 + "@manifoldxyz/royalty-registry-solidity": ^2.0.3 + "@nomicfoundation/hardhat-chai-matchers": ^1.0.6 + "@nomicfoundation/hardhat-network-helpers": ^1.0.0 + "@nomicfoundation/hardhat-toolbox": ^2.0.2 + "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13" + "@nomiclabs/hardhat-etherscan": ^3.1.7 + "@openzeppelin/contracts": ^4.9.0 + "@openzeppelin/contracts-upgradeable": ^4.9.0 + "@openzeppelin/hardhat-upgrades": ^1.28.0 + "@sandbox-smart-contracts/dependency-metatx": "*" + "@typechain/ethers-v5": ^10.2.1 + "@typechain/hardhat": ^6.1.6 + "@types/chai": ^4.3.5 + "@types/mocha": ^10.0.1 + "@types/node": ^20.1.2 + "@typescript-eslint/eslint-plugin": ^5.59.8 + "@typescript-eslint/parser": ^5.59.8 + chai: ^4.3.7 + dotenv: ^16.1.4 + eslint: ^8.41.0 + eslint-config-prettier: ^8.8.0 + eslint-plugin-mocha: ^10.1.0 + eslint-plugin-prettier: ^4.2.1 + ethers: ^5.7.2 + hardhat: ^2.14.1 + hardhat-gas-reporter: ^1.0.9 + prettier: ^2.8.8 + prettier-plugin-solidity: 1.0.0-beta.11 + solhint: ^3.4.1 + solhint-plugin-prettier: ^0.0.5 + solidity-coverage: ^0.8.2 + ts-node: ^10.9.1 + typechain: ^8.1.1 + typescript: ^5.0.4 + languageName: unknown + linkType: soft + "@sandbox-smart-contracts/deploy@workspace:packages/deploy": version: 0.0.0-use.local resolution: "@sandbox-smart-contracts/deploy@workspace:packages/deploy" @@ -1967,6 +2435,9 @@ __metadata: "@nomicfoundation/hardhat-chai-matchers": 1 "@nomicfoundation/hardhat-network-helpers": ^1.0.8 "@nomiclabs/hardhat-ethers": ^2.2.3 + "@sandbox-smart-contracts/asset": "*" + "@sandbox-smart-contracts/dependency-operator-filter": "*" + "@sandbox-smart-contracts/dependency-royalty-management": "*" "@sandbox-smart-contracts/giveaway": 0.0.3 "@typechain/ethers-v5": ^11.0.0 "@typechain/hardhat": ^8.0.0 @@ -2043,6 +2514,16 @@ __metadata: languageName: node linkType: hard +"@sandbox-smart-contracts/giveaway@workspace:packages/giveaway": +"@sandbox-smart-contracts/giveaway@npm:0.0.3": + version: 0.0.3 + resolution: "@sandbox-smart-contracts/giveaway@npm:0.0.3" + dependencies: + "@openzeppelin/contracts-upgradeable": ^4.9.0 + checksum: 8f7794b9e8dd9422f56b016794ad22985f4cd737a40d3121084e47e74d1e812c1e79ccf9ea3880e609abd445e339f28e0131fc6bf8e83c2237cd66d901c74239 + languageName: node + linkType: hard + "@sandbox-smart-contracts/giveaway@workspace:packages/giveaway": version: 0.0.0-use.local resolution: "@sandbox-smart-contracts/giveaway@workspace:packages/giveaway" @@ -2057,6 +2538,7 @@ __metadata: "@nomiclabs/hardhat-etherscan": ^3.1.7 "@openzeppelin/contracts-upgradeable": ^4.9.0 "@release-it/keep-a-changelog": ^4.0.0 + "@release-it/keep-a-changelog": ^4.0.0 "@typechain/ethers-v5": ^10.1.0 "@typechain/hardhat": ^6.1.2 "@types/chai": ^4.3.5 @@ -2077,6 +2559,7 @@ __metadata: prettier: ^2.8.8 prettier-plugin-solidity: ^1.1.3 release-it: ^16.1.5 + release-it: ^16.1.5 solhint: ^3.4.1 solhint-plugin-prettier: ^0.0.5 solidity-coverage: ^0.8.2 @@ -2087,9 +2570,9 @@ __metadata: linkType: soft "@scure/base@npm:~1.1.0": - version: 1.1.2 - resolution: "@scure/base@npm:1.1.2" - checksum: f666b09dbd62ecb5fe6d0e7a629c8a86a972a47dc4f4555ebbbd7b09782b10a5f894fed9c3b8c74fd683b1588c064df079a44e9f695c075ccd98c30a8d3e91f7 + version: 1.1.3 + resolution: "@scure/base@npm:1.1.3" + checksum: 1606ab8a4db898cb3a1ada16c15437c3bce4e25854fadc8eb03ae93cbbbac1ed90655af4b0be3da37e12056fef11c0374499f69b9e658c9e5b7b3e06353c630c languageName: node linkType: hard @@ -2115,6 +2598,17 @@ __metadata: languageName: node linkType: hard +"@scure/bip32@npm:1.3.1": + version: 1.3.1 + resolution: "@scure/bip32@npm:1.3.1" + dependencies: + "@noble/curves": ~1.1.0 + "@noble/hashes": ~1.3.1 + "@scure/base": ~1.1.0 + checksum: 394d65f77a40651eba21a5096da0f4233c3b50d422864751d373fcf142eeedb94a1149f9ab1dbb078086dab2d0bc27e2b1afec8321bf22d4403c7df2fea5bfe2 + languageName: node + linkType: hard + "@scure/bip39@npm:1.1.1": version: 1.1.1 resolution: "@scure/bip39@npm:1.1.1" @@ -2135,6 +2629,16 @@ __metadata: languageName: node linkType: hard +"@scure/bip39@npm:1.2.1": + version: 1.2.1 + resolution: "@scure/bip39@npm:1.2.1" + dependencies: + "@noble/hashes": ~1.3.0 + "@scure/base": ~1.1.0 + checksum: c5bd6f1328fdbeae2dcdd891825b1610225310e5e62a4942714db51066866e4f7bef242c7b06a1b9dcc8043a4a13412cf5c5df76d3b10aa9e36b82e9b6e3eeaa + languageName: node + linkType: hard + "@sentry/core@npm:5.30.0": version: 5.30.0 resolution: "@sentry/core@npm:5.30.0" @@ -2224,12 +2728,12 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^2.2.2": - version: 2.2.2 - resolution: "@smithy/types@npm:2.2.2" +"@smithy/types@npm:^2.3.3": + version: 2.3.4 + resolution: "@smithy/types@npm:2.3.4" dependencies: tslib: ^2.5.0 - checksum: 2799a14620da60efb2a0aba1bf9adc553a5446dc447b9ee1d7a95410233a70dff2b5e563fecf84388137dabbe662c6bf3a2247ca20a1f266c1256f82e0f25fcf + checksum: 12a500a02a52bace78532f1cb87c03dcba3132b3593b0a7dd7a5f0db7deb06710717f0d1d5a1d6455a0cfb20fa1dc8934e0c8c117d4dd20bfff8f52bc45a7075 languageName: node linkType: hard @@ -2269,6 +2773,15 @@ __metadata: languageName: node linkType: hard +"@szmarczak/http-timer@npm:^5.0.1": + version: 5.0.1 + resolution: "@szmarczak/http-timer@npm:5.0.1" + dependencies: + defer-to-connect: ^2.0.1 + checksum: fc9cb993e808806692e4a3337c90ece0ec00c89f4b67e3652a356b89730da98bc824273a6d67ca84d5f33cd85f317dcd5ce39d8cc0a2f060145a608a7cb8ce92 + languageName: node + linkType: hard + "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" @@ -2283,6 +2796,13 @@ __metadata: languageName: node linkType: hard +"@tootallnate/quickjs-emscripten@npm:^0.23.0": + version: 0.23.0 + resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0" + checksum: c350a2947ffb80b22e14ff35099fd582d1340d65723384a0fd0515e905e2534459ad2f301a43279a37308a27c99273c932e64649abd57d0bb3ca8c557150eccc + languageName: node + linkType: hard + "@tsconfig/node10@npm:^1.0.7": version: 1.0.9 resolution: "@tsconfig/node10@npm:1.0.9" @@ -2311,7 +2831,7 @@ __metadata: languageName: node linkType: hard -"@typechain/ethers-v5@npm:^10.1.0": +"@typechain/ethers-v5@npm:^10.1.0, @typechain/ethers-v5@npm:^10.2.1": version: 10.2.1 resolution: "@typechain/ethers-v5@npm:10.2.1" dependencies: @@ -2357,7 +2877,7 @@ __metadata: languageName: node linkType: hard -"@typechain/hardhat@npm:^6.1.2": +"@typechain/hardhat@npm:^6.1.2, @typechain/hardhat@npm:^6.1.6": version: 6.1.6 resolution: "@typechain/hardhat@npm:6.1.6" dependencies: @@ -2388,9 +2908,9 @@ __metadata: linkType: hard "@types/abstract-leveldown@npm:*": - version: 7.2.2 - resolution: "@types/abstract-leveldown@npm:7.2.2" - checksum: 1216eac3f9c21a58c0207b170bd734d29cf2d3d55537a3f4794a63f4d7d717549eea9cfaded7437a5d7cfd445ef808f0315c7525fcf7be803a0e5aa6a4dccfad + version: 7.2.3 + resolution: "@types/abstract-leveldown@npm:7.2.3" + checksum: 5c74d91712d9e8fee74612feb8c932af5aaa26a70259f1d178095edf4c3ff3e886bec53895382594c026a9179a3dd433c1fc6a7c2e04b0bebc4543c5b37f1c3c languageName: node linkType: hard @@ -2404,27 +2924,27 @@ __metadata: linkType: hard "@types/bn.js@npm:^5.1.0": - version: 5.1.1 - resolution: "@types/bn.js@npm:5.1.1" + version: 5.1.2 + resolution: "@types/bn.js@npm:5.1.2" dependencies: "@types/node": "*" - checksum: e50ed2dd3abe997e047caf90e0352c71e54fc388679735217978b4ceb7e336e51477791b715f49fd77195ac26dd296c7bad08a3be9750e235f9b2e1edb1b51c2 + checksum: 8d9fdb43836646c2ecd445041de03e057f9b459885be57faee64104160487a63730b9f371e8ad7d33f360b3cc6dc0e323543962fc5fa296b92b322b946732be0 languageName: node linkType: hard "@types/chai-as-promised@npm:^7.1.3": - version: 7.1.5 - resolution: "@types/chai-as-promised@npm:7.1.5" + version: 7.1.6 + resolution: "@types/chai-as-promised@npm:7.1.6" dependencies: "@types/chai": "*" - checksum: 7c1345c6e32513d52d8e562ec173c23161648d6b792046525f18803a9932d7b3ad3dca8f0181e3c529ec42b106099f174e34edeb184d61dc93e32c98b5132fd4 + checksum: f765dd249ae9384540f8e6402bd3a9f5e87b97f9078ef58f4b5ec15f7c3673e1f10f0089f819eceb20e00b3df40b7aae1bd44d2b8f4edbbedfcb33ce296f6791 languageName: node linkType: hard "@types/chai@npm:*, @types/chai@npm:^4.2.11, @types/chai@npm:^4.3.5": - version: 4.3.5 - resolution: "@types/chai@npm:4.3.5" - checksum: c8f26a88c6b5b53a3275c7f5ff8f107028e3cbb9ff26795fff5f3d9dea07106a54ce9e2dce5e40347f7c4cc35657900aaf0c83934a25a1ae12e61e0f5516e431 + version: 4.3.6 + resolution: "@types/chai@npm:4.3.6" + checksum: 32a6c18bf53fb3dbd89d1bfcadb1c6fd45cc0007c34e436393cc37a0a5a556f9e6a21d1e8dd71674c40cc36589d2f30bf4d9369d7787021e54d6e997b0d7300a languageName: node linkType: hard @@ -2438,19 +2958,19 @@ __metadata: linkType: hard "@types/eslint@npm:^8": - version: 8.44.2 - resolution: "@types/eslint@npm:8.44.2" + version: 8.44.3 + resolution: "@types/eslint@npm:8.44.3" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: 25b3ef61bae96350026593c9914c8a61ee02fde48ab8d568a73ee45032f13c0028c62e47a5ff78715af488dfe8e8bba913f7d30f859f60c7f9e639d328e80482 + checksum: 3a0d152785400cb83a887a646d9c8877468e686b6fb439635c64856b70dbe91019e588d2b32bc923cd60642bf5dca7f70b2cf61eb431cf25fbdf2932f6e13dd3 languageName: node linkType: hard "@types/estree@npm:*": - version: 1.0.1 - resolution: "@types/estree@npm:1.0.1" - checksum: e9aa175eacb797216fafce4d41e8202c7a75555bc55232dee0f9903d7171f8f19f0ae7d5191bb1a88cb90e65468be508c0df850a9fb81b4433b293a5a749899d + version: 1.0.2 + resolution: "@types/estree@npm:1.0.2" + checksum: aeedb1b2fe20cbe06f44b99b562bf9703e360bfcdf5bb3d61d248182ee1dd63500f2474e12f098ffe1f5ac3202b43b3e18ec99902d9328d5374f5512fa077e45 languageName: node linkType: hard @@ -2483,9 +3003,9 @@ __metadata: linkType: hard "@types/http-cache-semantics@npm:^4.0.1": - version: 4.0.1 - resolution: "@types/http-cache-semantics@npm:4.0.1" - checksum: 1048aacf627829f0d5f00184e16548205cd9f964bf0841c29b36bc504509230c40bc57c39778703a1c965a6f5b416ae2cbf4c1d4589c889d2838dd9dbfccf6e9 + version: 4.0.2 + resolution: "@types/http-cache-semantics@npm:4.0.2" + checksum: 513429786a45d8124f93cc7ea1454b692008190ef743e9fec75a6a3c998309782d216f1e67d7d497ffece9c9212310ae05a8c56e8955492ee400eacdd7620e61 languageName: node linkType: hard @@ -2500,9 +3020,9 @@ __metadata: linkType: hard "@types/json-schema@npm:*, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.9": - version: 7.0.12 - resolution: "@types/json-schema@npm:7.0.12" - checksum: 00239e97234eeb5ceefb0c1875d98ade6e922bfec39dd365ec6bd360b5c2f825e612ac4f6e5f1d13601b8b30f378f15e6faa805a3a732f4a1bbe61915163d293 + version: 7.0.13 + resolution: "@types/json-schema@npm:7.0.13" + checksum: 345df21a678fa72fb389f35f33de77833d09d4a142bb2bcb27c18690efa4cf70fc2876e43843cefb3fbdb9fcb12cd3e970a90936df30f53bbee899865ff605ab languageName: node linkType: hard @@ -2539,16 +3059,16 @@ __metadata: linkType: hard "@types/minimist@npm:^1.2.2": - version: 1.2.2 - resolution: "@types/minimist@npm:1.2.2" - checksum: b8da83c66eb4aac0440e64674b19564d9d86c80ae273144db9681e5eeff66f238ade9515f5006ffbfa955ceff8b89ad2bd8ec577d7caee74ba101431fb07045d + version: 1.2.3 + resolution: "@types/minimist@npm:1.2.3" + checksum: 666ea4f8c39dcbdfbc3171fe6b3902157c845cc9cb8cee33c10deb706cda5e0cc80f98ace2d6d29f6774b0dc21180c96cd73c592a1cbefe04777247c7ba0e84b languageName: node linkType: hard "@types/mocha@npm:^10.0.1": - version: 10.0.1 - resolution: "@types/mocha@npm:10.0.1" - checksum: 224ea9fce7b1734ccdb9aa99a622d902a538ce1847bca7fd22c5fb38adcf3ed536f50f48f587085db988a4bb3c2eb68f4b98e1cd6a38bc5547bd3bbbedc54495 + version: 10.0.2 + resolution: "@types/mocha@npm:10.0.2" + checksum: a78a02691f102beb02f9ec435458107d21b518fc477c3b2f37c90b8e70b67bff888351715ae173bd31ede25ee5e0d688aefb0faf4284034d08ba63027c8b0c01 languageName: node linkType: hard @@ -2559,10 +3079,10 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.2.5": - version: 20.5.7 - resolution: "@types/node@npm:20.5.7" - checksum: fc284c8e16ddc04569730d58e87eae349eb1c3dd9020cb79a1862d9d9add6f04e7367a236f3252db8db2572f90278e250f4cd43d27d264972b54394eaba1ed76 +"@types/node@npm:*, @types/node@npm:^20.1.2, @types/node@npm:^20.2.5": + version: 20.8.2 + resolution: "@types/node@npm:20.8.2" + checksum: 3da73e25d821bfcdb7de98589027e08bb4848e55408671c4a83ec0341e124b5313a0b20e1e4b4eff1168ea17a86f622ad73fcb04b761abd77496b9a27cbd5de5 languageName: node linkType: hard @@ -2581,9 +3101,9 @@ __metadata: linkType: hard "@types/node@npm:^14.10.2": - version: 14.18.56 - resolution: "@types/node@npm:14.18.56" - checksum: 990cd0e853caa264586aa703ed923767fb445ad240e54cfe7c877c8db2e0b377f85c1bc4b80575c7f07dc9f4c56bdfbc6b5c2704a689cf7c8f9ac4ec2ed84975 + version: 14.18.63 + resolution: "@types/node@npm:14.18.63" + checksum: be909061a54931778c71c49dc562586c32f909c4b6197e3d71e6dac726d8bd9fccb9f599c0df99f52742b68153712b5097c0f00cac4e279fa894b0ea6719a8fd languageName: node linkType: hard @@ -2618,9 +3138,9 @@ __metadata: linkType: hard "@types/qs@npm:^6.2.31, @types/qs@npm:^6.9.7": - version: 6.9.7 - resolution: "@types/qs@npm:6.9.7" - checksum: 7fd6f9c25053e9b5bb6bc9f9f76c1d89e6c04f7707a7ba0e44cc01f17ef5284adb82f230f542c2d5557d69407c9a40f0f3515e8319afd14e1e16b5543ac6cdba + version: 6.9.8 + resolution: "@types/qs@npm:6.9.8" + checksum: c28e07d00d07970e5134c6eed184a0189b8a4649e28fdf36d9117fe671c067a44820890de6bdecef18217647a95e9c6aebdaaae69f5fe4b0bec9345db885f77e languageName: node linkType: hard @@ -2635,27 +3155,27 @@ __metadata: linkType: hard "@types/secp256k1@npm:^4.0.1": - version: 4.0.3 - resolution: "@types/secp256k1@npm:4.0.3" + version: 4.0.4 + resolution: "@types/secp256k1@npm:4.0.4" dependencies: "@types/node": "*" - checksum: 1bd10b9afa724084b655dc81b7b315def3d2d0e272014ef16009fa76e17537411c07c0695fdea412bc7b36d2a02687f5fea33522d55b8ef29eda42992f812913 + checksum: 6f521a08486a98e71c8529f5c3119f99e610196a47243cc6052c6160b216dff2c85dc50a8f3208ed47028dbb470bbb6fdee47a3fdc064687e46021d5a712767c languageName: node linkType: hard "@types/semver@npm:^7.3.12": - version: 7.5.1 - resolution: "@types/semver@npm:7.5.1" - checksum: 2fffe938c7ac168711f245a16e1856a3578d77161ca17e29a05c3e02c7be3e9c5beefa29a3350f6c1bd982fb70aa28cc52e4845eb7d36246bcdc0377170d584d + version: 7.5.3 + resolution: "@types/semver@npm:7.5.3" + checksum: 349fdd1ab6c213bac5c991bac766bd07b8b12e63762462bb058740dcd2eb09c8193d068bb226f134661275f2022976214c0e727a4e5eb83ec1b131127c980d3e languageName: node linkType: hard "@types/through@npm:*": - version: 0.0.30 - resolution: "@types/through@npm:0.0.30" + version: 0.0.31 + resolution: "@types/through@npm:0.0.31" dependencies: "@types/node": "*" - checksum: 9578470db0b527c26e246a1220ae9bffc6bf47f20f89c54aac467c083ab1f7e16c00d9a7b4bb6cb4e2dfae465027270827e5908a6236063f6214625e50585d78 + checksum: 8c4a58e17816dc5013559517c48a697c1cb48a76d26716210dcf4d57272eba0d9d8888a1d88f7b9cee47b4acfcc9cf29aee27ec53cc43d57b5391d20881037fd languageName: node linkType: hard @@ -2907,12 +3427,12 @@ __metadata: linkType: hard "@yarnpkg/parsers@npm:^3.0.0-rc.18": - version: 3.0.0-rc.50 - resolution: "@yarnpkg/parsers@npm:3.0.0-rc.50" + version: 3.0.0-rc.53 + resolution: "@yarnpkg/parsers@npm:3.0.0-rc.53" dependencies: js-yaml: ^3.10.0 tslib: ^2.4.0 - checksum: 6f7843e53f100ffa74a1285aca563b72feda32cc6deacb7176810c5a4ad9f4d3fcd1f5da8e9057ef16dd9dc37c4d8f5ce8926153d26ea84334197ff6b5ed60b3 + checksum: ef20025d8ddb1f31a919fbd8a2535d169d42632aa178d2d782ce8165bae326865ea6900130bf0975d953d870904321862ecd77477be56a0bd475490b5785e6fc languageName: node linkType: hard @@ -3062,7 +3582,7 @@ __metadata: languageName: node linkType: hard -"agent-base@npm:^7.0.1, agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": version: 7.1.0 resolution: "agent-base@npm:7.1.0" dependencies: @@ -3072,11 +3592,14 @@ __metadata: linkType: hard "agentkeepalive@npm:^4.2.1": + version: 4.5.0 + resolution: "agentkeepalive@npm:4.5.0" version: 4.5.0 resolution: "agentkeepalive@npm:4.5.0" dependencies: humanize-ms: ^1.2.1 checksum: 13278cd5b125e51eddd5079f04d6fe0914ac1b8b91c1f3db2c1822f99ac1a7457869068997784342fe455d59daaff22e14fb7b8c3da4e741896e7e31faf92481 + checksum: 13278cd5b125e51eddd5079f04d6fe0914ac1b8b91c1f3db2c1822f99ac1a7457869068997784342fe455d59daaff22e14fb7b8c3da4e741896e7e31faf92481 languageName: node linkType: hard @@ -3115,15 +3638,15 @@ __metadata: linkType: hard "amazon-cognito-identity-js@npm:^6.0.1": - version: 6.3.5 - resolution: "amazon-cognito-identity-js@npm:6.3.5" + version: 6.3.6 + resolution: "amazon-cognito-identity-js@npm:6.3.6" dependencies: "@aws-crypto/sha256-js": 1.2.2 buffer: 4.9.2 fast-base64-decode: ^1.0.0 isomorphic-unfetch: ^3.0.0 js-cookie: ^2.2.1 - checksum: d1c2030d482004a82d58e3977e418da268ea34a3418e136dece50714d719ac6b62b0f19214f41b5660797e01e730b0fb2fa7f8cf3c21bc5710da11b89e0f8851 + checksum: 4f69d8618269fe0b081a1625a38f33af476e97ff6d4c8b79ea182169f16ed086bb01b5024e0a8af692029637a4c34203a2bb00666cbf52a133216220d43e31d8 languageName: node linkType: hard @@ -3143,6 +3666,15 @@ __metadata: languageName: node linkType: hard +"ansi-align@npm:^3.0.1": + version: 3.0.1 + resolution: "ansi-align@npm:3.0.1" + dependencies: + string-width: ^4.1.0 + checksum: 6abfa08f2141d231c257162b15292467081fa49a208593e055c866aa0455b57f3a86b5a678c190c618faa79b4c59e254493099cb700dd9cf2293c6be2c8f5d8d + languageName: node + linkType: hard + "ansi-colors@npm:3.2.3": version: 3.2.3 resolution: "ansi-colors@npm:3.2.3" @@ -3171,6 +3703,7 @@ __metadata: languageName: node linkType: hard +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2": "ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -3241,9 +3774,9 @@ __metadata: linkType: hard "antlr4@npm:^4.11.0": - version: 4.13.0 - resolution: "antlr4@npm:4.13.0" - checksum: 9fc5d8bf2d3be7e35e372ef70acd015e9e593ff7482dafd9780185eb63e156958b137a6e4af1792eda71adc7c3b09f9087d2d7794b903c1a65f58800907e7beb + version: 4.13.1 + resolution: "antlr4@npm:4.13.1" + checksum: 76dcb0c8ed2d0b83a16641579668088919f51d1288551604e3cdff46c67955b3eef25892aead9de1eca203b3968536fa952e6931f35ba877780af37971c055f1 languageName: node linkType: hard @@ -3345,55 +3878,56 @@ __metadata: linkType: hard "array.prototype.findlast@npm:^1.2.2": - version: 1.2.2 - resolution: "array.prototype.findlast@npm:1.2.2" + version: 1.2.3 + resolution: "array.prototype.findlast@npm:1.2.3" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 es-shim-unscopables: ^1.0.0 - get-intrinsic: ^1.1.3 - checksum: 4be14199176d26f48a5dec87c2e0545acf829f7557357238679acf2b7ae6fa5bf7dde7e9dfe9ce2ccc9e8691a9c99adc623bbe312ba476a5935497f3d7c5cd29 + get-intrinsic: ^1.2.1 + checksum: 853d359bac5c4ce7354e5f2f2930f09eb47eeed18b6d6fb630cf6fa1fe4f32217fd27d07ee4aeeb3d1fd710538cf7bc00d4efc34df64da49fff0b13f57b0d66f languageName: node linkType: hard "array.prototype.map@npm:^1.0.5": - version: 1.0.5 - resolution: "array.prototype.map@npm:1.0.5" + version: 1.0.6 + resolution: "array.prototype.map@npm:1.0.6" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 es-array-method-boxes-properly: ^1.0.0 is-string: ^1.0.7 - checksum: 70c4ecdd39480a51cfe84d18e4839a5f05d0b5d2785fee6838cd2bd5f86a17340a734ce7bb90c16804a70cead214b6f42c3d285f92267e11ccc0abd1880fe3b5 + checksum: dfba063cdfb5faba9ee32d5836dc23f3963c2bf7c7ea7d745ee0a96bacf663cbb32ab0bf17d8f65ac6e8c91a162efdea8edbc8b36aed9d17687ce482ba60d91f languageName: node linkType: hard -"array.prototype.reduce@npm:^1.0.5": - version: 1.0.5 - resolution: "array.prototype.reduce@npm:1.0.5" +"array.prototype.reduce@npm:^1.0.6": + version: 1.0.6 + resolution: "array.prototype.reduce@npm:1.0.6" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 es-array-method-boxes-properly: ^1.0.0 is-string: ^1.0.7 - checksum: f44691395f9202aba5ec2446468d4c27209bfa81464f342ae024b7157dbf05b164e47cca01250b8c7c2a8219953fb57651cca16aab3d16f43b85c0d92c26eef3 + checksum: c709c3f5caa2aac4fb10e0c6c1982cca50328a2a48658d53b1da8ee3a78069ad67cdac21296d6285521aa3a932a8178c0e192b5fc831fae2977b69a5a8a64ad7 languageName: node linkType: hard -"arraybuffer.prototype.slice@npm:^1.0.1": - version: 1.0.1 - resolution: "arraybuffer.prototype.slice@npm:1.0.1" +"arraybuffer.prototype.slice@npm:^1.0.2": + version: 1.0.2 + resolution: "arraybuffer.prototype.slice@npm:1.0.2" dependencies: array-buffer-byte-length: ^1.0.0 call-bind: ^1.0.2 define-properties: ^1.2.0 + es-abstract: ^1.22.1 get-intrinsic: ^1.2.1 is-array-buffer: ^3.0.2 is-shared-array-buffer: ^1.0.2 - checksum: e3e9b2a3e988ebfeddce4c7e8f69df730c9e48cb04b0d40ff0874ce3d86b3d1339dd520ffde5e39c02610bc172ecfbd4bc93324b1cabd9554c44a56b131ce0ce + checksum: c200faf437786f5b2c80d4564ff5481c886a16dee642ef02abdc7306c7edd523d1f01d1dd12b769c7eb42ac9bc53874510db19a92a2c035c0f6696172aafa5d3 languageName: node linkType: hard @@ -3450,6 +3984,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.13.4": + version: 0.13.4 + resolution: "ast-types@npm:0.13.4" + dependencies: + tslib: ^2.0.1 + checksum: 5a51f7b70588ecced3601845a0e203279ca2f5fdc184416a0a1640c93ec0a267241d6090a328e78eebb8de81f8754754e0a4f1558ba2a3d638f8ccbd0b1f0eff + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -3466,6 +4009,7 @@ __metadata: languageName: node linkType: hard +"async-retry@npm:1.3.3, async-retry@npm:^1.3.3": "async-retry@npm:1.3.3, async-retry@npm:^1.3.3": version: 1.3.3 resolution: "async-retry@npm:1.3.3" @@ -3526,14 +4070,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.0.0": - version: 1.5.0 - resolution: "axios@npm:1.5.0" +"axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.5.1": + version: 1.5.1 + resolution: "axios@npm:1.5.1" dependencies: follow-redirects: ^1.15.0 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: e7405a5dbbea97760d0e6cd58fecba311b0401ddb4a8efbc4108f5537da9b3f278bde566deb777935a960beec4fa18e7b8353881f2f465e4f2c0e949fead35be + checksum: 4444f06601f4ede154183767863d2b8e472b4a6bfc5253597ed6d21899887e1fd0ee2b3de792ac4f8459fe2e359d2aa07c216e45fd8b9e4e0688a6ebf48a5a8d languageName: node linkType: hard @@ -3567,7 +4111,14 @@ __metadata: languageName: node linkType: hard -"bcrypt-pbkdf@npm:^1.0.0": +"basic-ftp@npm:^5.0.2": + version: 5.0.3 + resolution: "basic-ftp@npm:5.0.3" + checksum: 8b04e88eb85a64de9311721bb0707c9cd70453eefdd854cab85438e6f46fb6c597ddad57ed1acf0a9ede3c677b14e657f51051688a5f23d6f3ea7b5d9073b850 + languageName: node + linkType: hard + +"bcrypt-pbkdf@npm:^1.0.0": version: 1.0.2 resolution: "bcrypt-pbkdf@npm:1.0.2" dependencies: @@ -3597,6 +4148,20 @@ __metadata: languageName: node linkType: hard +"before-after-hook@npm:^2.2.0": + version: 2.2.3 + resolution: "before-after-hook@npm:2.2.3" + checksum: a1a2430976d9bdab4cd89cb50d27fa86b19e2b41812bf1315923b0cba03371ebca99449809226425dd3bcef20e010db61abdaff549278e111d6480034bebae87 + languageName: node + linkType: hard + +"big-integer@npm:^1.6.44": + version: 1.6.51 + resolution: "big-integer@npm:1.6.51" + checksum: 3d444173d1b2e20747e2c175568bedeebd8315b0637ea95d75fd27830d3b8e8ba36c6af40374f36bdaea7b5de376dcada1b07587cb2a79a928fccdb6e6e3c518 + languageName: node + linkType: hard + "bigint-crypto-utils@npm:^3.0.23": version: 3.3.0 resolution: "bigint-crypto-utils@npm:3.3.0" @@ -3605,6 +4170,9 @@ __metadata: linkType: hard "bignumber.js@npm:^9.0.0": + version: 9.1.2 + resolution: "bignumber.js@npm:9.1.2" + checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf version: 9.1.2 resolution: "bignumber.js@npm:9.1.2" checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf @@ -3618,6 +4186,7 @@ __metadata: languageName: node linkType: hard +"bl@npm:^4.0.3, bl@npm:^4.1.0": "bl@npm:^4.0.3, bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" @@ -3640,6 +4209,17 @@ __metadata: languageName: node linkType: hard +"bl@npm:^5.0.0": + version: 5.1.0 + resolution: "bl@npm:5.1.0" + dependencies: + buffer: ^6.0.3 + inherits: ^2.0.4 + readable-stream: ^3.4.0 + checksum: a7a438ee0bc540e80b8eb68cc1ad759a9c87df06874a99411d701d01cc0b36f30cd20050512ac3e77090138890960e07bfee724f3ee6619bb39a569f5cc3b1bc + languageName: node + linkType: hard + "blakejs@npm:^1.1.0": version: 1.2.1 resolution: "blakejs@npm:1.2.1" @@ -3700,6 +4280,31 @@ __metadata: languageName: node linkType: hard +"boxen@npm:^7.0.0": + version: 7.1.1 + resolution: "boxen@npm:7.1.1" + dependencies: + ansi-align: ^3.0.1 + camelcase: ^7.0.1 + chalk: ^5.2.0 + cli-boxes: ^3.0.0 + string-width: ^5.1.2 + type-fest: ^2.13.0 + widest-line: ^4.0.1 + wrap-ansi: ^8.1.0 + checksum: ad8833d5f2845b0a728fdf8a0bc1505dff0c518edcb0fd56979a08774b1f26cf48b71e66532179ccdfb9ed95b64aa008689cca26f7776f93f002b8000a683d76 + languageName: node + linkType: hard + +"bplist-parser@npm:^0.2.0": + version: 0.2.0 + resolution: "bplist-parser@npm:0.2.0" + dependencies: + big-integer: ^1.6.44 + checksum: d5339dd16afc51de6c88f88f58a45b72ed6a06aa31f5557d09877575f220b7c1d3fbe375da0b62e6a10d4b8ed80523567e351f24014f5bc886ad523758142cdd + languageName: node + linkType: hard + "brace-expansion@npm:^1.0.0, brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -3849,15 +4454,6 @@ __metadata: languageName: node linkType: hard -"busboy@npm:^1.6.0": - version: 1.6.0 - resolution: "busboy@npm:1.6.0" - dependencies: - streamsearch: ^1.1.0 - checksum: 32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e - languageName: node - linkType: hard - "bytes@npm:3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" @@ -3866,6 +4462,8 @@ __metadata: linkType: hard "cacache@npm:^17.0.0": + version: 17.1.4 + resolution: "cacache@npm:17.1.4" version: 17.1.4 resolution: "cacache@npm:17.1.4" dependencies: @@ -3874,6 +4472,7 @@ __metadata: glob: ^10.2.2 lru-cache: ^7.7.1 minipass: ^7.0.3 + minipass: ^7.0.3 minipass-collect: ^1.0.2 minipass-flush: ^1.0.5 minipass-pipeline: ^1.2.4 @@ -3892,6 +4491,29 @@ __metadata: languageName: node linkType: hard +"cacheable-request@npm:^10.2.8": + version: 10.2.13 + resolution: "cacheable-request@npm:10.2.13" + dependencies: + "@types/http-cache-semantics": ^4.0.1 + get-stream: ^6.0.1 + http-cache-semantics: ^4.1.1 + keyv: ^4.5.3 + mimic-response: ^4.0.0 + normalize-url: ^8.0.0 + responselike: ^3.0.0 + checksum: 1a2e9a20558ff2e23156bf945110f16d08037830a57c7b97ba9a145f6526fff1e1da21b1a1f9f4ee5fda77a482374e1a537b60dc23dab5df506f5a1cea5be9ab + checksum: b7751df756656954a51201335addced8f63fc53266fa56392c9f5ae83c8d27debffb4458ac2d168a744a4517ec3f2163af05c20097f93d17bdc2dc8a385e14a6 + languageName: node + linkType: hard + +"cacheable-lookup@npm:^7.0.0": + version: 7.0.0 + resolution: "cacheable-lookup@npm:7.0.0" + checksum: 9e2856763fc0a7347ab34d704c010440b819d4bb5e3593b664381b7433e942dd22e67ee5581f12256f908e79b82d30b86ebbacf40a081bfe10ee93fbfbc2d6a9 + languageName: node + linkType: hard + "cacheable-request@npm:^10.2.8": version: 10.2.13 resolution: "cacheable-request@npm:10.2.13" @@ -3945,6 +4567,13 @@ __metadata: languageName: node linkType: hard +"camelcase@npm:^7.0.1": + version: 7.0.1 + resolution: "camelcase@npm:7.0.1" + checksum: 86ab8f3ebf08bcdbe605a211a242f00ed30d8bfb77dab4ebb744dd36efbc84432d1c4adb28975ba87a1b8be40a80fbd1e60e2f06565315918fa7350011a26d3d + languageName: node + linkType: hard + "cardinal@npm:^2.1.1": version: 2.1.1 resolution: "cardinal@npm:2.1.1" @@ -3987,6 +4616,15 @@ __metadata: languageName: node linkType: hard +"cbor@npm:^9.0.0": + version: 9.0.1 + resolution: "cbor@npm:9.0.1" + dependencies: + nofilter: ^3.1.0 + checksum: 42333ac3d42cc3f6fcc7a529e68417a2dd8099eda43ca4be1304cdc5bc7494efe058e2db8a3d3b46ae60d69c7331ea813c22dbd019c4ac592d23e599d72bbcc9 + languageName: node + linkType: hard + "chai-as-promised@npm:^7.1.1": version: 7.1.1 resolution: "chai-as-promised@npm:7.1.1" @@ -3999,17 +4637,17 @@ __metadata: linkType: hard "chai@npm:^4.2.0, chai@npm:^4.3.7": - version: 4.3.8 - resolution: "chai@npm:4.3.8" + version: 4.3.10 + resolution: "chai@npm:4.3.10" dependencies: assertion-error: ^1.1.0 - check-error: ^1.0.2 - deep-eql: ^4.1.2 - get-func-name: ^2.0.0 - loupe: ^2.3.1 + 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.5 - checksum: 29e0984ed13308319cadc35437c8ef0a3e271544d226c991bf7e3b6d771bf89707321669e11d05e362bc0ad0bd26585079b989d1032f3c106e3bb95d7f079cce + type-detect: ^4.0.8 + checksum: 536668c60a0d985a0fbd94418028e388d243a925d7c5e858c7443e334753511614a3b6a124bac9ca077dfc4c37acc367d62f8c294960f440749536dc181dfc6d languageName: node linkType: hard @@ -4020,6 +4658,14 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^2.4.1, chalk@npm:^2.4.2": +"chalk@npm:5.3.0, chalk@npm:^5.0.0, chalk@npm:^5.0.1, chalk@npm:^5.2.0, chalk@npm:^5.3.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 623922e077b7d1e9dedaea6f8b9e9352921f8ae3afe739132e0e00c275971bdd331268183b2628cf4ab1727c45ea1f28d7e24ac23ce1db1eb653c414ca8a5a80 + languageName: node + linkType: hard + "chalk@npm:^2.4.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -4055,10 +4701,12 @@ __metadata: languageName: node linkType: hard -"check-error@npm:^1.0.2": - version: 1.0.2 - resolution: "check-error@npm:1.0.2" - checksum: d9d106504404b8addd1ee3f63f8c0eaa7cd962a1a28eb9c519b1c4a1dc7098be38007fc0060f045ee00f075fbb7a2a4f42abcf61d68323677e11ab98dc16042e +"check-error@npm:^1.0.2, check-error@npm:^1.0.3": + version: 1.0.3 + resolution: "check-error@npm:1.0.3" + dependencies: + get-func-name: ^2.0.2 + checksum: e2131025cf059b21080f4813e55b3c480419256914601750b0fee3bd9b2b8315b531e551ef12560419b8b6d92a3636511322752b1ce905703239e7cc451b6399 languageName: node linkType: hard @@ -4134,9 +4782,9 @@ __metadata: linkType: hard "ci-info@npm:^3.2.0": - version: 3.8.0 - resolution: "ci-info@npm:3.8.0" - checksum: d0a4d3160497cae54294974a7246202244fff031b0a6ea20dd57b10ec510aa17399c41a1b0982142c105f3255aff2173e5c0dd7302ee1b2f28ba3debda375098 + version: 3.9.0 + resolution: "ci-info@npm:3.9.0" + checksum: 6b19dc9b2966d1f8c2041a838217299718f15d6c4b63ae36e4674edd2bee48f780e94761286a56aa59eb305a85fbea4ddffb7630ec063e7ec7e7e5ad42549a87 languageName: node linkType: hard @@ -4178,6 +4826,13 @@ __metadata: languageName: node linkType: hard +"cli-boxes@npm:^3.0.0": + version: 3.0.0 + resolution: "cli-boxes@npm:3.0.0" + checksum: 637d84419d293a9eac40a1c8c96a2859e7d98b24a1a317788e13c8f441be052fc899480c6acab3acc82eaf1bccda6b7542d7cdcf5c9c3cc39227175dc098d5b2 + languageName: node + linkType: hard + "cli-cursor@npm:3.1.0, cli-cursor@npm:^3.1.0": version: 3.1.0 resolution: "cli-cursor@npm:3.1.0" @@ -4196,6 +4851,15 @@ __metadata: languageName: node linkType: hard +"cli-cursor@npm:^4.0.0": + version: 4.0.0 + resolution: "cli-cursor@npm:4.0.0" + dependencies: + restore-cursor: ^4.0.0 + checksum: ab3f3ea2076e2176a1da29f9d64f72ec3efad51c0960898b56c8a17671365c26e67b735920530eaf7328d61f8bd41c27f46b9cf6e4e10fe2fa44b5e8c0e392cc + languageName: node + linkType: hard + "cli-spinners@npm:2.6.1": version: 2.6.1 resolution: "cli-spinners@npm:2.6.1" @@ -4204,9 +4868,9 @@ __metadata: linkType: hard "cli-spinners@npm:^2.5.0, cli-spinners@npm:^2.9.0": - version: 2.9.0 - resolution: "cli-spinners@npm:2.9.0" - checksum: a9c56e1f44457d4a9f4f535364e729cb8726198efa9e98990cfd9eda9e220dfa4ba12f92808d1be5e29029cdfead781db82dc8549b97b31c907d55f96aa9b0e2 + version: 2.9.1 + resolution: "cli-spinners@npm:2.9.1" + checksum: 1780618be58309c469205bc315db697934bac68bce78cd5dfd46248e507a533172d623c7348ecfd904734f597ce0a4e5538684843d2cfb7af485d4466699940c languageName: node linkType: hard @@ -4260,6 +4924,13 @@ __metadata: languageName: node linkType: hard +"cli-width@npm:^4.1.0": + version: 4.1.0 + resolution: "cli-width@npm:4.1.0" + checksum: 0a79cff2dbf89ef530bcd54c713703ba94461457b11e5634bd024c78796ed21401e32349c004995954e06f442d82609287e7aabf6a5f02c919a1cf3b9b6854ff + languageName: node + linkType: hard + "cliui@npm:^5.0.0": version: 5.0.0 resolution: "cliui@npm:5.0.0" @@ -4300,6 +4971,13 @@ __metadata: languageName: node linkType: hard +"clone@npm:^1.0.2": + version: 1.0.4 + resolution: "clone@npm:1.0.4" + checksum: d06418b7335897209e77bdd430d04f882189582e67bd1f75a04565f3f07f5b3f119a9d670c943b6697d0afb100f03b866b3b8a1f91d4d02d72c4ecf2bb64b5dd + languageName: node + linkType: hard + "color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -4416,6 +5094,13 @@ __metadata: languageName: node linkType: hard +"compare-versions@npm:^6.0.0": + version: 6.1.0 + resolution: "compare-versions@npm:6.1.0" + checksum: d4e2a45706a023d8d0b6680338b66b79e20bd02d1947f0ac6531dab634cbed89fa373b3f03d503c5e489761194258d6e1bae67a07f88b1efc61648454f2d47e7 + languageName: node + linkType: hard + "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" @@ -4458,6 +5143,29 @@ __metadata: languageName: node linkType: hard +"config-chain@npm:^1.1.11": + version: 1.1.13 + resolution: "config-chain@npm:1.1.13" + dependencies: + ini: ^1.3.4 + proto-list: ~1.2.1 + checksum: 828137a28e7c2fc4b7fb229bd0cd6c1397bcf83434de54347e608154008f411749041ee392cbe42fab6307e02de4c12480260bf769b7d44b778fdea3839eafab + languageName: node + linkType: hard + +"configstore@npm:^6.0.0": + version: 6.0.0 + resolution: "configstore@npm:6.0.0" + dependencies: + dot-prop: ^6.0.1 + graceful-fs: ^4.2.6 + unique-string: ^3.0.0 + write-file-atomic: ^3.0.3 + xdg-basedir: ^5.0.1 + checksum: 81995351c10bc04c58507f17748477aeac6f47465109d20e3534cebc881d22e927cfd29e73dd852c46c55f62c2b7be4cd1fe6eb3a93ba51f7f9813c218f9bae0 + languageName: node + linkType: hard + "console-control-strings@npm:^1.1.0": version: 1.1.0 resolution: "console-control-strings@npm:1.1.0" @@ -4496,15 +5204,20 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:8.2.0, cosmiconfig@npm:^8.0.0": - version: 8.2.0 - resolution: "cosmiconfig@npm:8.2.0" +"cosmiconfig@npm:8.3.6, cosmiconfig@npm:^8.0.0": + version: 8.3.6 + resolution: "cosmiconfig@npm:8.3.6" dependencies: - import-fresh: ^3.2.1 + import-fresh: ^3.3.0 js-yaml: ^4.1.0 - parse-json: ^5.0.0 + parse-json: ^5.2.0 path-type: ^4.0.0 - checksum: 836d5d8efa750f3fb17b03d6ca74cd3154ed025dffd045304b3ef59637f662bde1e5dc88f8830080d180ec60841719cf4ea2ce73fb21ec694b16865c478ff297 + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: dc339ebea427898c9e03bf01b56ba7afbac07fc7d2a2d5a15d6e9c14de98275a9565da949375aee1809591c152c0a3877bb86dbeaf74d5bd5aaa79955ad9e7a0 languageName: node linkType: hard @@ -4603,6 +5316,15 @@ __metadata: languageName: node linkType: hard +"crypto-random-string@npm:^4.0.0": + version: 4.0.0 + resolution: "crypto-random-string@npm:4.0.0" + dependencies: + type-fest: ^1.0.1 + checksum: 91f148f27bcc8582798f0fb3e75a09d9174557f39c3c40a89dd1bd70fb5a14a02548245aa26fa7d663c426ac5026f4729841231c84f9e30e8c8ece5e38656741 + languageName: node + linkType: hard + "csv-generate@npm:^3.4.3": version: 3.4.3 resolution: "csv-generate@npm:3.4.3" @@ -4663,10 +5385,10 @@ __metadata: languageName: node linkType: hard -"data-uri-to-buffer@npm:^5.0.1": - version: 5.0.1 - resolution: "data-uri-to-buffer@npm:5.0.1" - checksum: 10958f89c0047b84bd86d572b6b77c9bf238ebe7b55a9a9ab04c90fbf5ab1881783b72e31dc0febdffd30ec914930244f2f728e3629bb8911d922baba129426f +"data-uri-to-buffer@npm:^6.0.0": + version: 6.0.1 + resolution: "data-uri-to-buffer@npm:6.0.1" + checksum: 9140e68c585ae33d950f5943bd476751346c8b789ae80b01a578a33cb8f7f706d1ca7378aff2b1878b2a6d9a8c88c55cc286d88191c8b8ead8255c3c4d934530 languageName: node linkType: hard @@ -4686,6 +5408,7 @@ __metadata: languageName: node linkType: hard +"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.0.1, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": "debug@npm:4, debug@npm:4.3.4, debug@npm:^4.0.1, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" @@ -4733,7 +5456,7 @@ __metadata: languageName: node linkType: hard -"deep-eql@npm:^4.0.1, deep-eql@npm:^4.1.2": +"deep-eql@npm:^4.0.1, deep-eql@npm:^4.1.3": version: 4.1.3 resolution: "deep-eql@npm:4.1.3" dependencies: @@ -4742,6 +5465,7 @@ __metadata: languageName: node linkType: hard +"deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": "deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -4787,6 +5511,37 @@ __metadata: languageName: node linkType: hard +"default-browser-id@npm:^3.0.0": + version: 3.0.0 + resolution: "default-browser-id@npm:3.0.0" + dependencies: + bplist-parser: ^0.2.0 + untildify: ^4.0.0 + checksum: 279c7ad492542e5556336b6c254a4eaf31b2c63a5433265655ae6e47301197b6cfb15c595a6fdc6463b2ff8e1a1a1ed3cba56038a60e1527ba4ab1628c6b9941 + languageName: node + linkType: hard + +"default-browser@npm:^4.0.0": + version: 4.0.0 + resolution: "default-browser@npm:4.0.0" + dependencies: + bundle-name: ^3.0.0 + default-browser-id: ^3.0.0 + execa: ^7.1.1 + titleize: ^3.0.0 + checksum: 40c5af984799042b140300be5639c9742599bda76dc9eba5ac9ad5943c83dd36cebc4471eafcfddf8e0ec817166d5ba89d56f08e66a126c7c7908a179cead1a7 + languageName: node + linkType: hard + +"defaults@npm:^1.0.3": + version: 1.0.4 + resolution: "defaults@npm:1.0.4" + dependencies: + clone: ^1.0.2 + checksum: 3a88b7a587fc076b84e60affad8b85245c01f60f38fc1d259e7ac1d89eb9ce6abb19e27215de46b98568dd5bc48471730b327637e6f20b0f1bc85cf00440c80a + languageName: node + linkType: hard + "defender-base-client@npm:1.44.0": version: 1.44.0 resolution: "defender-base-client@npm:1.44.0" @@ -4828,6 +5583,13 @@ __metadata: languageName: node linkType: hard +"defer-to-connect@npm:^2.0.1": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 8a9b50d2f25446c0bfefb55a48e90afd58f85b21bcf78e9207cd7b804354f6409032a1705c2491686e202e64fc05f147aa5aa45f9aa82627563f045937f5791b + languageName: node + linkType: hard + "deferred-leveldown@npm:~5.3.0": version: 5.3.0 resolution: "deferred-leveldown@npm:5.3.0" @@ -4838,6 +5600,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.0.1": + version: 1.1.0 + resolution: "define-data-property@npm:1.1.0" + dependencies: + get-intrinsic: ^1.2.1 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.0 + checksum: 7ad4ee84cca8ad427a4831f5693526804b62ce9dfd4efac77214e95a4382aed930072251d4075dc8dc9fc949a353ed51f19f5285a84a788ba9216cc51472a093 + languageName: node + linkType: hard + "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" @@ -4852,13 +5625,21 @@ __metadata: languageName: node linkType: hard +"define-lazy-prop@npm:^3.0.0": + version: 3.0.0 + resolution: "define-lazy-prop@npm:3.0.0" + checksum: 54884f94caac0791bf6395a3ec530ce901cf71c47b0196b8754f3fd17edb6c0e80149c1214429d851873bb0d689dbe08dcedbb2306dc45c8534a5934723851b6 + languageName: node + linkType: hard + "define-properties@npm:^1.1.2, define-properties@npm:^1.1.3, define-properties@npm:^1.1.4, define-properties@npm:^1.2.0": - version: 1.2.0 - resolution: "define-properties@npm:1.2.0" + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" dependencies: + define-data-property: ^1.0.1 has-property-descriptors: ^1.0.0 object-keys: ^1.1.1 - checksum: e60aee6a19b102df4e2b1f301816804e81ab48bb91f00d0d935f269bf4b3f79c88b39e4f89eaa132890d23267335fd1140dfcd8d5ccd61031a0a2c41a54e33a6 + checksum: b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 languageName: node linkType: hard @@ -4887,6 +5668,7 @@ __metadata: languageName: node linkType: hard +"depd@npm:2.0.0": "depd@npm:2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" @@ -4902,9 +5684,9 @@ __metadata: linkType: hard "detect-newline@npm:^4.0.0": - version: 4.0.0 - resolution: "detect-newline@npm:4.0.0" - checksum: 52767347c70f485b2d1db6493dde57b8c3c1f249e24bad7eb7424cc1129200aa7e671902ede18bc94a8b69e10dec91456aab4c7e2478559d9eedb31ef3847f36 + version: 4.0.1 + resolution: "detect-newline@npm:4.0.1" + checksum: 0409ecdfb93419591ccff24fccfe2ddddad29b66637d1ed898872125b25af05014fdeedc9306339577060f69f59fe6e9830cdd80948597f136dfbffefa60599c languageName: node linkType: hard @@ -4985,6 +5767,15 @@ __metadata: languageName: node linkType: hard +"dot-prop@npm:^6.0.1": + version: 6.0.1 + resolution: "dot-prop@npm:6.0.1" + dependencies: + is-obj: ^2.0.0 + checksum: 0f47600a4b93e1dc37261da4e6909652c008832a5d3684b5bf9a9a0d3f4c67ea949a86dceed9b72f5733ed8e8e6383cc5958df3bbd0799ee317fd181f2ece700 + languageName: node + linkType: hard + "dotenv-cli@npm:^4.0.0": version: 4.1.1 resolution: "dotenv-cli@npm:4.1.1" @@ -5000,16 +5791,20 @@ __metadata: linkType: hard "dotenv-cli@npm:^7.2.1": + version: 7.3.0 + resolution: "dotenv-cli@npm:7.3.0" version: 7.3.0 resolution: "dotenv-cli@npm:7.3.0" dependencies: cross-spawn: ^7.0.3 dotenv: ^16.3.0 + dotenv: ^16.3.0 dotenv-expand: ^10.0.0 minimist: ^1.2.6 bin: dotenv: cli.js checksum: bc48e9872ed451aa7633cfde0079f5e4b40837d49dca4eab947682c80f524bd1e63ec31ff69b7cf955ff969185a05a343dd5d754dd5569e4ae31f8e9a790ab1b + checksum: bc48e9872ed451aa7633cfde0079f5e4b40837d49dca4eab947682c80f524bd1e63ec31ff69b7cf955ff969185a05a343dd5d754dd5569e4ae31f8e9a790ab1b languageName: node linkType: hard @@ -5027,6 +5822,7 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.1.3, dotenv@npm:^16.1.4, dotenv@npm:^16.3.0": "dotenv@npm:^16.1.3, dotenv@npm:^16.1.4, dotenv@npm:^16.3.0": version: 16.3.1 resolution: "dotenv@npm:16.3.1" @@ -5103,6 +5899,13 @@ __metadata: languageName: node linkType: hard +"emoji-regex@npm:^10.2.1": + version: 10.2.1 + resolution: "emoji-regex@npm:10.2.1" + checksum: 1aa2d16881c56531fdfc03d0b36f5c2b6221cc4097499a5665b88b711dc3fb4d5b8804f0ca6f00c56e5dcf89bac75f0487eee85da1da77df3a33accc6ecbe426 + languageName: node + linkType: hard + "emoji-regex@npm:^7.0.1": version: 7.0.3 resolution: "emoji-regex@npm:7.0.3" @@ -5214,17 +6017,17 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.20.4, es-abstract@npm:^1.21.2, es-abstract@npm:^1.22.1": - version: 1.22.1 - resolution: "es-abstract@npm:1.22.1" +"es-abstract@npm:^1.22.1": + version: 1.22.2 + resolution: "es-abstract@npm:1.22.2" dependencies: array-buffer-byte-length: ^1.0.0 - arraybuffer.prototype.slice: ^1.0.1 + arraybuffer.prototype.slice: ^1.0.2 available-typed-arrays: ^1.0.5 call-bind: ^1.0.2 es-set-tostringtag: ^2.0.1 es-to-primitive: ^1.2.1 - function.prototype.name: ^1.1.5 + function.prototype.name: ^1.1.6 get-intrinsic: ^1.2.1 get-symbol-description: ^1.0.0 globalthis: ^1.0.3 @@ -5240,24 +6043,24 @@ __metadata: is-regex: ^1.1.4 is-shared-array-buffer: ^1.0.2 is-string: ^1.0.7 - is-typed-array: ^1.1.10 + is-typed-array: ^1.1.12 is-weakref: ^1.0.2 object-inspect: ^1.12.3 object-keys: ^1.1.1 object.assign: ^4.1.4 - regexp.prototype.flags: ^1.5.0 - safe-array-concat: ^1.0.0 + regexp.prototype.flags: ^1.5.1 + safe-array-concat: ^1.0.1 safe-regex-test: ^1.0.0 - string.prototype.trim: ^1.2.7 - string.prototype.trimend: ^1.0.6 - string.prototype.trimstart: ^1.0.6 + string.prototype.trim: ^1.2.8 + string.prototype.trimend: ^1.0.7 + string.prototype.trimstart: ^1.0.7 typed-array-buffer: ^1.0.0 typed-array-byte-length: ^1.0.0 typed-array-byte-offset: ^1.0.0 typed-array-length: ^1.0.4 unbox-primitive: ^1.0.2 - which-typed-array: ^1.1.10 - checksum: 614e2c1c3717cb8d30b6128ef12ea110e06fd7d75ad77091ca1c5dbfb00da130e62e4bbbbbdda190eada098a22b27fe0f99ae5a1171dac2c8663b1e8be8a3a9b + which-typed-array: ^1.1.11 + checksum: cc70e592d360d7d729859013dee7a610c6b27ed8630df0547c16b0d16d9fe6505a70ee14d1af08d970fdd132b3f88c9ca7815ce72c9011608abf8ab0e55fc515 languageName: node linkType: hard @@ -5285,6 +6088,23 @@ __metadata: languageName: node linkType: hard +"es-get-iterator@npm:^1.0.2": + version: 1.1.3 + resolution: "es-get-iterator@npm:1.1.3" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.1.3 + has-symbols: ^1.0.3 + is-arguments: ^1.1.1 + is-map: ^2.0.2 + is-set: ^2.0.2 + is-string: ^1.0.7 + isarray: ^2.0.5 + stop-iteration-iterator: ^1.0.0 + checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.1": version: 2.0.1 resolution: "es-set-tostringtag@npm:2.0.1" @@ -5305,6 +6125,15 @@ __metadata: languageName: node linkType: hard +"es-shim-unscopables@npm:^1.0.0": + version: 1.0.0 + resolution: "es-shim-unscopables@npm:1.0.0" + dependencies: + has: ^1.0.3 + checksum: 83e95cadbb6ee44d3644dfad60dcad7929edbc42c85e66c3e99aefd68a3a5c5665f2686885cddb47dfeabfd77bd5ea5a7060f2092a955a729bbd8834f0d86fa1 + languageName: node + linkType: hard + "es-to-primitive@npm:^1.2.1": version: 1.2.1 resolution: "es-to-primitive@npm:1.2.1" @@ -5330,6 +6159,13 @@ __metadata: languageName: node linkType: hard +"escape-goat@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-goat@npm:4.0.0" + checksum: 7034e0025eec7b751074b837f10312c5b768493265bdad046347c0aadbc1e652776f7e5df94766473fecb5d3681169cc188fe9ccc1e22be53318c18be1671cc0 + languageName: node + linkType: hard + "escape-string-regexp@npm:1.0.5, escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -5351,6 +6187,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e + languageName: node + linkType: hard + "escodegen@npm:1.7.x": version: 1.7.1 resolution: "escodegen@npm:1.7.1" @@ -5407,6 +6250,24 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:^2.1.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" + dependencies: + esprima: ^4.0.1 + estraverse: ^5.2.0 + esutils: ^2.0.2 + source-map: ~0.6.1 + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 096696407e161305cd05aebb95134ad176708bc5cb13d0dcc89a5fcbb959b8ed757e7f2591a5f8036f8f4952d4a724de0df14cd419e29212729fa6df5ce16bf6 + languageName: node + linkType: hard + "eslint-config-prettier@npm:^6.11.0": version: 6.15.0 resolution: "eslint-config-prettier@npm:6.15.0" @@ -5442,14 +6303,14 @@ __metadata: linkType: hard "eslint-plugin-mocha@npm:^10.1.0": - version: 10.1.0 - resolution: "eslint-plugin-mocha@npm:10.1.0" + version: 10.2.0 + resolution: "eslint-plugin-mocha@npm:10.2.0" dependencies: eslint-utils: ^3.0.0 - rambda: ^7.1.0 + rambda: ^7.4.0 peerDependencies: eslint: ">=7.0.0" - checksum: 67c063ba190fe8ab3186baaf800a375e9f16a17f69deaac2ea0d1825f6e4260f9a56bd510ceb2ffbe6644d7090beda0efbd2ab7824e4852ce2abee53a1086179 + checksum: d284812141ea18b9dcd1f173477e364bda2b86a621cd2a1c13636065255d32498df33b5d9a6fa1d64b187bd86819a7707ae8b0895228a9f545f12ed153fac1a2 languageName: node linkType: hard @@ -5534,6 +6395,10 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": + version: 3.4.3 + resolution: "eslint-visitor-keys@npm:3.4.3" + checksum: 36e9ef87fca698b6fd7ca5ca35d7b2b6eeaaf106572e2f7fd31c12d3bfdaccdb587bba6d3621067e5aece31c8c3a348b93922ab8f7b2cbc6aaab5e1d89040c60 "eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" @@ -5592,14 +6457,14 @@ __metadata: linkType: hard "eslint@npm:^8.41.0, eslint@npm:^8.43.0": - version: 8.48.0 - resolution: "eslint@npm:8.48.0" + version: 8.50.0 + resolution: "eslint@npm:8.50.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.6.1 "@eslint/eslintrc": ^2.1.2 - "@eslint/js": 8.48.0 - "@humanwhocodes/config-array": ^0.11.10 + "@eslint/js": 8.50.0 + "@humanwhocodes/config-array": ^0.11.11 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 ajv: ^6.12.4 @@ -5610,6 +6475,7 @@ __metadata: escape-string-regexp: ^4.0.0 eslint-scope: ^7.2.2 eslint-visitor-keys: ^3.4.3 + eslint-visitor-keys: ^3.4.3 espree: ^9.6.1 esquery: ^1.4.2 esutils: ^2.0.2 @@ -5634,7 +6500,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: f20b359a4f8123fec5c033577368cc020d42978b1b45303974acd8da7a27063168ee3fe297ab5b35327162f6a93154063e3ce6577102f70f9809aff793db9bd0 + checksum: 9ebfe5615dc84700000d218e32ddfdcfc227ca600f65f18e5541ec34f8902a00356a9a8804d9468fd6c8637a5ef6a3897291dad91ba6579d5b32ffeae5e31768 languageName: node linkType: hard @@ -5690,6 +6556,7 @@ __metadata: languageName: node linkType: hard +"esprima@npm:^4.0.0, esprima@npm:^4.0.1, esprima@npm:~4.0.0": "esprima@npm:^4.0.0, esprima@npm:^4.0.1, esprima@npm:~4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" @@ -5747,22 +6614,20 @@ __metadata: linkType: hard "eth-gas-reporter@npm:^0.2.25": - version: 0.2.25 - resolution: "eth-gas-reporter@npm:0.2.25" + version: 0.2.27 + resolution: "eth-gas-reporter@npm:0.2.27" dependencies: - "@ethersproject/abi": ^5.0.0-beta.146 "@solidity-parser/parser": ^0.14.0 + axios: ^1.5.1 cli-table3: ^0.5.0 colors: 1.4.0 ethereum-cryptography: ^1.0.3 - ethers: ^4.0.40 + ethers: ^5.7.2 fs-readdir-recursive: ^1.1.0 lodash: ^4.17.14 markdown-table: ^1.1.3 - mocha: ^7.1.1 + mocha: ^10.2.0 req-cwd: ^2.0.0 - request: ^2.88.0 - request-promise-native: ^1.0.5 sha1: ^1.1.1 sync-request: ^6.0.0 peerDependencies: @@ -5770,7 +6635,7 @@ __metadata: peerDependenciesMeta: "@codechecks/client": optional: true - checksum: 3bfa81e554b069bb817f2a073a601a0429e6b582c56ad99db0727dc2a102ab00fc27888820b8a042a194a8fb7d40954d10cd7b011ede6b8170285d2d5a88666c + checksum: 9a26a4936693de6dbe633a9e6f9d69eb93c9d45c61ecbc20702a72f15ade424785e29ae8e62ea3a2afc49ea22a4777a71914dc8da1b8587e9d47d085a3246784 languageName: node linkType: hard @@ -5851,6 +6716,18 @@ __metadata: languageName: node linkType: hard +"ethereum-cryptography@npm:^2.0.0, ethereum-cryptography@npm:^2.1.2": + version: 2.1.2 + resolution: "ethereum-cryptography@npm:2.1.2" + dependencies: + "@noble/curves": 1.1.0 + "@noble/hashes": 1.3.1 + "@scure/bip32": 1.3.1 + "@scure/bip39": 1.2.1 + checksum: 2e8f7b8cc90232ae838ab6a8167708e8362621404d26e79b5d9e762c7b53d699f7520aff358d9254de658fcd54d2d0af168ff909943259ed27dc4cef2736410c + languageName: node + linkType: hard + "ethereumjs-abi@npm:^0.6.8": version: 0.6.8 resolution: "ethereumjs-abi@npm:0.6.8" @@ -5891,7 +6768,7 @@ __metadata: languageName: node linkType: hard -"ethereumjs-util@npm:^7.1.3, ethereumjs-util@npm:^7.1.4, ethereumjs-util@npm:^7.1.5": +"ethereumjs-util@npm:^7.0.3, ethereumjs-util@npm:^7.1.3, ethereumjs-util@npm:^7.1.4, ethereumjs-util@npm:^7.1.5": version: 7.1.5 resolution: "ethereumjs-util@npm:7.1.5" dependencies: @@ -5942,24 +6819,9 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^4.0.40": - version: 4.0.49 - resolution: "ethers@npm:4.0.49" - dependencies: - aes-js: 3.0.0 - bn.js: ^4.11.9 - elliptic: 6.5.4 - hash.js: 1.1.3 - js-sha3: 0.5.7 - scrypt-js: 2.0.4 - setimmediate: 1.0.4 - uuid: 2.0.1 - xmlhttprequest: 1.8.0 - checksum: 357115348a5f1484c7745fae1d852876788216c7d94c072c80132192f1800c4d388433ea2456750856641d6d4eed8a3b41847eb44f5e1c42139963864e3bcc38 - languageName: node - linkType: hard - "ethers@npm:^6.6.2": + version: 6.7.1 + resolution: "ethers@npm:6.7.1" version: 6.7.1 resolution: "ethers@npm:6.7.1" dependencies: @@ -5971,6 +6833,7 @@ __metadata: tslib: 2.4.0 ws: 8.5.0 checksum: 07833692e3f53b18e28c4cba9f53f3d5ebff8360de02ad57b2584c00c52b88f5b790373f9b9f6b4f6b52ffa2074530a6101192b30c3260f7cdeff929d34bb88b + checksum: 07833692e3f53b18e28c4cba9f53f3d5ebff8360de02ad57b2584c00c52b88f5b790373f9b9f6b4f6b52ffa2074530a6101192b30c3260f7cdeff929d34bb88b languageName: node linkType: hard @@ -6029,6 +6892,23 @@ __metadata: languageName: node linkType: hard +"execa@npm:7.2.0, execa@npm:^7.1.1": + version: 7.2.0 + resolution: "execa@npm:7.2.0" + dependencies: + cross-spawn: ^7.0.3 + get-stream: ^6.0.1 + human-signals: ^4.3.0 + is-stream: ^3.0.0 + merge-stream: ^2.0.0 + npm-run-path: ^5.1.0 + onetime: ^6.0.0 + signal-exit: ^3.0.7 + strip-final-newline: ^3.0.0 + checksum: 14fd17ba0ca8c87b277584d93b1d9fc24f2a65e5152b31d5eb159a3b814854283eaae5f51efa9525e304447e2f757c691877f7adff8fde5746aae67eb1edd1cc + languageName: node + linkType: hard + "execa@npm:^1.0.0": version: 1.0.0 resolution: "execa@npm:1.0.0" @@ -6061,6 +6941,23 @@ __metadata: languageName: node linkType: hard +"execa@npm:^5.0.0, execa@npm:^5.1.1": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: ^7.0.3 + get-stream: ^6.0.0 + human-signals: ^2.1.0 + is-stream: ^2.0.0 + merge-stream: ^2.0.0 + npm-run-path: ^4.0.1 + onetime: ^5.1.2 + signal-exit: ^3.0.3 + strip-final-newline: ^2.0.0 + checksum: fba9022c8c8c15ed862847e94c252b3d946036d7547af310e344a527e59021fd8b6bb0723883ea87044dc4f0201f949046993124a42ccb0855cae5bf8c786343 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -6075,6 +6972,7 @@ __metadata: languageName: node linkType: hard +"external-editor@npm:^3.0.3, external-editor@npm:^3.1.0": "external-editor@npm:^3.0.3, external-editor@npm:^3.1.0": version: 3.1.0 resolution: "external-editor@npm:3.1.0" @@ -6134,6 +7032,7 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0": "fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0": version: 3.3.1 resolution: "fast-glob@npm:3.3.1" @@ -6194,6 +7093,16 @@ __metadata: languageName: node linkType: hard +"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4": + version: 3.2.0 + resolution: "fetch-blob@npm:3.2.0" + dependencies: + node-domexception: ^1.0.0 + web-streams-polyfill: ^3.0.3 + checksum: f19bc28a2a0b9626e69fd7cf3a05798706db7f6c7548da657cbf5026a570945f5eeaedff52007ea35c8bcd3d237c58a20bf1543bc568ab2422411d762dd3d5bf + languageName: node + linkType: hard + "figures@npm:3.2.0, figures@npm:^3.0.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -6213,6 +7122,16 @@ __metadata: languageName: node linkType: hard +"figures@npm:^5.0.0": + version: 5.0.0 + resolution: "figures@npm:5.0.0" + dependencies: + escape-string-regexp: ^5.0.0 + is-unicode-supported: ^1.2.0 + checksum: e6e8b6d1df2f554d4effae4a5ceff5d796f9449f6d4e912d74dab7d5f25916ecda6c305b9084833157d56485a0c78b37164430ddc5675bcee1330e346710669e + languageName: node + linkType: hard + "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -6279,13 +7198,18 @@ __metadata: linkType: hard "flat-cache@npm:^3.0.4": + version: 3.1.0 + resolution: "flat-cache@npm:3.1.0" version: 3.1.0 resolution: "flat-cache@npm:3.1.0" dependencies: + flatted: ^3.2.7 + keyv: ^4.5.3 flatted: ^3.2.7 keyv: ^4.5.3 rimraf: ^3.0.2 checksum: 99312601d5b90f44aef403f17f056dc09be7e437703740b166cdc9386d99e681f74e6b6e8bd7d010bda66904ea643c9527276b1b80308a2119741d94108a4d8f + checksum: 99312601d5b90f44aef403f17f056dc09be7e437703740b166cdc9386d99e681f74e6b6e8bd7d010bda66904ea643c9527276b1b80308a2119741d94108a4d8f languageName: node linkType: hard @@ -6310,9 +7234,9 @@ __metadata: linkType: hard "flatted@npm:^3.2.7": - version: 3.2.7 - resolution: "flatted@npm:3.2.7" - checksum: 427633049d55bdb80201c68f7eb1cbd533e03eac541f97d3aecab8c5526f12a20ccecaeede08b57503e772c769e7f8680b37e8d482d1e5f8d7e2194687f9ea35 + version: 3.2.9 + resolution: "flatted@npm:3.2.9" + checksum: f14167fbe26a9d20f6fca8d998e8f1f41df72c8e81f9f2c9d61ed2bea058248f5e1cbd05e7f88c0e5087a6a0b822a1e5e2b446e879f3cfbe0b07ba2d7f80b026 languageName: node linkType: hard @@ -6326,12 +7250,12 @@ __metadata: linkType: hard "follow-redirects@npm:^1.12.1, follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.15.0": - version: 1.15.2 - resolution: "follow-redirects@npm:1.15.2" + version: 1.15.3 + resolution: "follow-redirects@npm:1.15.3" peerDependenciesMeta: debug: optional: true - checksum: faa66059b66358ba65c234c2f2a37fcec029dc22775f35d9ad6abac56003268baf41e55f9ee645957b32c7d9f62baf1f0b906e68267276f54ec4b4c597c2b190 + checksum: 584da22ec5420c837bd096559ebfb8fe69d82512d5585004e36a3b4a6ef6d5905780e0c74508c7b72f907d1fa2b7bd339e613859e9c304d0dc96af2027fd0231 languageName: node linkType: hard @@ -6368,6 +7292,13 @@ __metadata: languageName: node linkType: hard +"form-data-encoder@npm:^2.1.2": + version: 2.1.4 + resolution: "form-data-encoder@npm:2.1.4" + checksum: e0b3e5950fb69b3f32c273944620f9861f1933df9d3e42066e038e26dfb343d0f4465de9f27e0ead1a09d9df20bc2eed06a63c2ca2f8f00949e7202bae9e29dd + languageName: node + linkType: hard + "form-data@npm:^2.2.0": version: 2.5.1 resolution: "form-data@npm:2.5.1" @@ -6410,6 +7341,15 @@ __metadata: languageName: node linkType: hard +"formdata-polyfill@npm:^4.0.10": + version: 4.0.10 + resolution: "formdata-polyfill@npm:4.0.10" + dependencies: + fetch-blob: ^3.1.2 + checksum: 82a34df292afadd82b43d4a740ce387bc08541e0a534358425193017bf9fb3567875dc5f69564984b1da979979b70703aa73dee715a17b6c229752ae736dd9db + languageName: node + linkType: hard + "fp-ts@npm:1.19.3": version: 1.19.3 resolution: "fp-ts@npm:1.19.3" @@ -6510,10 +7450,14 @@ __metadata: linkType: hard "fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" version: 3.0.3 resolution: "fs-minipass@npm:3.0.3" dependencies: minipass: ^7.0.3 + checksum: 8722a41109130851d979222d3ec88aabaceeaaf8f57b2a8f744ef8bd2d1ce95453b04a61daa0078822bc5cd21e008814f06fe6586f56fef511e71b8d2394d802 + minipass: ^7.0.3 checksum: 8722a41109130851d979222d3ec88aabaceeaaf8f57b2a8f744ef8bd2d1ce95453b04a61daa0078822bc5cd21e008814f06fe6586f56fef511e71b8d2394d802 languageName: node linkType: hard @@ -6543,11 +7487,14 @@ __metadata: linkType: hard "fsevents@npm:~2.3.1, fsevents@npm:~2.3.2": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: node-gyp: latest checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 + checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 conditions: os=darwin languageName: node linkType: hard @@ -6562,6 +7509,8 @@ __metadata: linkType: hard "fsevents@patch:fsevents@~2.3.1#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -6577,7 +7526,7 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.5": +"function.prototype.name@npm:^1.1.6": version: 1.1.6 resolution: "function.prototype.name@npm:1.1.6" dependencies: @@ -6585,6 +7534,10 @@ __metadata: define-properties: ^1.2.0 es-abstract: ^1.22.1 functions-have-names: ^1.2.3 + checksum: 7a3f9bd98adab09a07f6e1f03da03d3f7c26abbdeaeee15223f6c04a9fb5674792bdf5e689dac19b97ac71de6aad2027ba3048a9b883aa1b3173eed6ab07f479 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + functions-have-names: ^1.2.3 checksum: 7a3f9bd98adab09a07f6e1f03da03d3f7c26abbdeaeee15223f6c04a9fb5674792bdf5e689dac19b97ac71de6aad2027ba3048a9b883aa1b3173eed6ab07f479 languageName: node linkType: hard @@ -6596,6 +7549,7 @@ __metadata: languageName: node linkType: hard +"functions-have-names@npm:^1.2.3": "functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" @@ -6658,10 +7612,10 @@ __metadata: languageName: node linkType: hard -"get-func-name@npm:^2.0.0": - version: 2.0.0 - resolution: "get-func-name@npm:2.0.0" - checksum: 8d82e69f3e7fab9e27c547945dfe5cc0c57fc0adf08ce135dddb01081d75684a03e7a0487466f478872b341d52ac763ae49e660d01ab83741f74932085f693c3 +"get-func-name@npm:^2.0.0, get-func-name@npm:^2.0.2": + version: 2.0.2 + resolution: "get-func-name@npm:2.0.2" + checksum: 3f62f4c23647de9d46e6f76d2b3eafe58933a9b3830c60669e4180d6c601ce1b4aa310ba8366143f55e52b139f992087a9f0647274e8745621fa2af7e0acf13b languageName: node linkType: hard @@ -6707,6 +7661,13 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^6.0.0, get-stream@npm:^6.0.1": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: e04ecece32c92eebf5b8c940f51468cd53554dcbb0ea725b2748be583c9523d00128137966afce410b9b051eb2ef16d657cd2b120ca8edafcf5a65e81af63cad + languageName: node + linkType: hard + "get-symbol-description@npm:^1.0.0": version: 1.0.0 resolution: "get-symbol-description@npm:1.0.0" @@ -6718,14 +7679,14 @@ __metadata: linkType: hard "get-uri@npm:^6.0.1": - version: 6.0.1 - resolution: "get-uri@npm:6.0.1" + version: 6.0.2 + resolution: "get-uri@npm:6.0.2" dependencies: basic-ftp: ^5.0.2 - data-uri-to-buffer: ^5.0.1 + data-uri-to-buffer: ^6.0.0 debug: ^4.3.4 fs-extra: ^8.1.0 - checksum: a8aec70e1c67386fbe67f66e344ecd671a19f4cfc8e0f0e14d070563af5123d540e77fbceb6e26566f29846fac864d2862699ab134d307f85c85e7d72ce23d14 + checksum: 762de3b0e3d4e7afc966e4ce93be587d70c270590da9b4c8fbff888362656c055838d926903d1774cbfeed4d392b4d6def4b2c06d48c050580070426a3a8629b languageName: node linkType: hard @@ -6769,6 +7730,25 @@ __metadata: languageName: node linkType: hard +"git-up@npm:^7.0.0": + version: 7.0.0 + resolution: "git-up@npm:7.0.0" + dependencies: + is-ssh: ^1.4.0 + parse-url: ^8.1.0 + checksum: 2faadbab51e94d2ffb220e426e950087cc02c15d664e673bd5d1f734cfa8196fed8b19493f7bf28fe216d087d10e22a7fd9b63687e0ba7d24f0ddcfb0a266d6e + languageName: node + linkType: hard + +"git-url-parse@npm:13.1.0": + version: 13.1.0 + resolution: "git-url-parse@npm:13.1.0" + dependencies: + git-up: ^7.0.0 + checksum: 212a9b0343e9199998b6a532efe2014476a7a1283af393663ca49ac28d4768929aad16d3322e2685236065ee394dbc93e7aa63a48956531e984c56d8b5edb54d + languageName: node + linkType: hard + "glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.0, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -6871,17 +7851,17 @@ __metadata: linkType: hard "glob@npm:^10.2.2": - version: 10.3.3 - resolution: "glob@npm:10.3.3" + version: 10.3.10 + resolution: "glob@npm:10.3.10" dependencies: foreground-child: ^3.1.0 - jackspeak: ^2.0.3 + jackspeak: ^2.3.5 minimatch: ^9.0.1 minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 path-scurry: ^1.10.1 bin: - glob: dist/cjs/src/bin.js - checksum: 29190d3291f422da0cb40b77a72fc8d2c51a36524e99b8bf412548b7676a6627489528b57250429612b6eec2e6fe7826d328451d3e694a9d15e575389308ec53 + glob: dist/esm/bin.mjs + checksum: 4f2fe2511e157b5a3f525a54092169a5f92405f24d2aed3142f4411df328baca13059f4182f1db1bf933e2c69c0bd89e57ae87edd8950cba8c7ccbe84f721cf3 languageName: node linkType: hard @@ -6933,6 +7913,15 @@ __metadata: languageName: node linkType: hard +"global-dirs@npm:^3.0.0": + version: 3.0.1 + resolution: "global-dirs@npm:3.0.1" + dependencies: + ini: 2.0.0 + checksum: 70147b80261601fd40ac02a104581432325c1c47329706acd773f3a6ce99bb36d1d996038c85ccacd482ad22258ec233c586b6a91535b1a116b89663d49d6438 + languageName: node + linkType: hard + "global-modules@npm:^2.0.0": version: 2.0.0 resolution: "global-modules@npm:2.0.0" @@ -6954,11 +7943,11 @@ __metadata: linkType: hard "globals@npm:^13.19.0, globals@npm:^13.6.0, globals@npm:^13.9.0": - version: 13.21.0 - resolution: "globals@npm:13.21.0" + version: 13.22.0 + resolution: "globals@npm:13.22.0" dependencies: type-fest: ^0.20.2 - checksum: 86c92ca8a04efd864c10852cd9abb1ebe6d447dcc72936783e66eaba1087d7dba5c9c3421a48d6ca722c319378754dbcc3f3f732dbe47592d7de908edf58a773 + checksum: 64af5a09565341432770444085f7aa98b54331c3b69732e0de411003921fa2dd060222ae7b50bec0b98f29c4d00b4f49bf434049ba9f7c36ca4ee1773f60458c languageName: node linkType: hard @@ -6984,6 +7973,19 @@ __metadata: languageName: node linkType: hard +"globby@npm:13.2.2": + version: 13.2.2 + resolution: "globby@npm:13.2.2" + dependencies: + dir-glob: ^3.0.1 + fast-glob: ^3.3.0 + ignore: ^5.2.4 + merge2: ^1.4.1 + slash: ^4.0.0 + checksum: f3d84ced58a901b4fcc29c846983108c426631fe47e94872868b65565495f7bee7b3defd68923bd480582771fd4bbe819217803a164a618ad76f1d22f666f41e + languageName: node + linkType: hard + "globby@npm:^10.0.1": version: 10.0.2 resolution: "globby@npm:10.0.2" @@ -7120,7 +8122,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.1.9, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.1.9, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 @@ -7241,6 +8243,8 @@ __metadata: linkType: hard "hardhat-deploy@npm:^0.11.30": + version: 0.11.37 + resolution: "hardhat-deploy@npm:0.11.37" version: 0.11.37 resolution: "hardhat-deploy@npm:0.11.37" dependencies: @@ -7269,6 +8273,7 @@ __metadata: qs: ^6.9.4 zksync-web3: ^0.14.3 checksum: c338289849f26530296be648c7bfc2d4673d0786855ed256ee9cc864f40b94125cfa36808bedfbae4f2bad7adc38def7547bbeb3b84cbfb0aeabae04de5238fd + checksum: c338289849f26530296be648c7bfc2d4673d0786855ed256ee9cc864f40b94125cfa36808bedfbae4f2bad7adc38def7547bbeb3b84cbfb0aeabae04de5238fd languageName: node linkType: hard @@ -7286,8 +8291,8 @@ __metadata: linkType: hard "hardhat@npm:^2.14.1": - version: 2.17.2 - resolution: "hardhat@npm:2.17.2" + version: 2.17.4 + resolution: "hardhat@npm:2.17.4" dependencies: "@ethersproject/abi": ^5.1.2 "@metamask/eth-sig-util": ^4.0.0 @@ -7301,6 +8306,16 @@ __metadata: "@nomicfoundation/ethereumjs-tx": 5.0.2 "@nomicfoundation/ethereumjs-util": 9.0.2 "@nomicfoundation/ethereumjs-vm": 7.0.2 + "@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 @@ -7347,7 +8362,7 @@ __metadata: optional: true bin: hardhat: internal/cli/bootstrap.js - checksum: 7c80f45354c82e812e04ab75e6cab40c1e561969265762f5d254365beecd6bb261186d3da445de5963ca2e1125bf495f3263aa9f762f436d8920ca4551e31204 + checksum: da8762f29ac08b6178edaedf1bf4641e8bcf44759c944906af644519fa9d0d3fb6c30e87add3904d8899f9cebfbde47a8422e219ad0bb24226c6636f2d3ef7c2 languageName: node linkType: hard @@ -7500,12 +8515,17 @@ __metadata: languageName: node linkType: hard +"has-yarn@npm:^3.0.0": + version: 3.0.0 + resolution: "has-yarn@npm:3.0.0" + checksum: b9e14e78e0a37bc070550c862b201534287bc10e62a86ec9c1f455ffb082db42817ce9aed914bd73f1d589bbf268520e194629ff2f62ff6b98a482c4bd2dcbfb + languageName: node + linkType: hard + "has@npm:^1.0.3": - version: 1.0.3 - resolution: "has@npm:1.0.3" - dependencies: - function-bind: ^1.1.1 - checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792 + version: 1.0.4 + resolution: "has@npm:1.0.4" + checksum: 8a11ba062e0627c9578a1d08285401e39f1d071a9692ddf793199070edb5648b21c774dd733e2a181edd635bf6862731885f476f4ccf67c998d7a5ff7cef2550 languageName: node linkType: hard @@ -7520,16 +8540,6 @@ __metadata: languageName: node linkType: hard -"hash.js@npm:1.1.3": - version: 1.1.3 - resolution: "hash.js@npm:1.1.3" - dependencies: - inherits: ^2.0.3 - minimalistic-assert: ^1.0.0 - checksum: 93de6f178bf71feee38f66868a57ecb5602d937c1ccd69951b0bfec1488813b6afdbb4a81ddb2c62488c419b4a35af352298b006f14c9cfbf5b872c4191b657f - languageName: node - linkType: hard - "hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3, hash.js@npm:^1.1.7": version: 1.1.7 resolution: "hash.js@npm:1.1.7" @@ -7620,6 +8630,16 @@ __metadata: languageName: node linkType: hard +"http-proxy-agent@npm:^7.0.0": + version: 7.0.0 + resolution: "http-proxy-agent@npm:7.0.0" + dependencies: + agent-base: ^7.1.0 + debug: ^4.3.4 + checksum: 48d4fac997917e15f45094852b63b62a46d0c8a4f0b9c6c23ca26d27b8df8d178bed88389e604745e748bd9a01f5023e25093722777f0593c3f052009ff438b6 + languageName: node + linkType: hard + "http-response-object@npm:^3.0.1": version: 3.0.2 resolution: "http-response-object@npm:3.0.2" @@ -7650,6 +8670,16 @@ __metadata: languageName: node linkType: hard +"http2-wrapper@npm:^2.1.10": + version: 2.2.0 + resolution: "http2-wrapper@npm:2.2.0" + dependencies: + quick-lru: ^5.1.1 + resolve-alpn: ^1.2.0 + checksum: 6fd20e5cb6a58151715b3581e06a62a47df943187d2d1f69e538a50cccb7175dd334ecfde7900a37d18f3e13a1a199518a2c211f39860e81e9a16210c199cfaa + languageName: node + linkType: hard + "https-proxy-agent@npm:^5.0.0": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" @@ -7660,13 +8690,13 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.0": - version: 7.0.1 - resolution: "https-proxy-agent@npm:7.0.1" +"https-proxy-agent@npm:^7.0.2": + version: 7.0.2 + resolution: "https-proxy-agent@npm:7.0.2" dependencies: agent-base: ^7.0.2 debug: 4 - checksum: 2d765c31865071373771f53abdd72912567b76015a4eff61094f586194192950cd89257d50f0e621807a16c083bc8cad5852e3885c6ba154d2ce721a18fac248 + checksum: 088969a0dd476ea7a0ed0a2cf1283013682b08f874c3bc6696c83fa061d2c157d29ef0ad3eb70a2046010bb7665573b2388d10fdcb3e410a66995e5248444292 languageName: node linkType: hard @@ -7747,13 +8777,16 @@ __metadata: linkType: hard "immutable@npm:^4.0.0-rc.12": + version: 4.3.4 + resolution: "immutable@npm:4.3.4" + checksum: de3edd964c394bab83432429d3fb0b4816b42f56050f2ca913ba520bd3068ec3e504230d0800332d3abc478616e8f55d3787424a90d0952e6aba864524f1afc3 version: 4.3.4 resolution: "immutable@npm:4.3.4" checksum: de3edd964c394bab83432429d3fb0b4816b42f56050f2ca913ba520bd3068ec3e504230d0800332d3abc478616e8f55d3787424a90d0952e6aba864524f1afc3 languageName: node linkType: hard -"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": +"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" dependencies: @@ -7770,6 +8803,13 @@ __metadata: languageName: node linkType: hard +"import-lazy@npm:^4.0.0": + version: 4.0.0 + resolution: "import-lazy@npm:4.0.0" + checksum: 22f5e51702134aef78890156738454f620e5fe7044b204ebc057c614888a1dd6fdf2ede0fdcca44d5c173fd64f65c985f19a51775b06967ef58cc3d26898df07 + languageName: node + linkType: hard + "imul@npm:^1.0.0": version: 1.0.1 resolution: "imul@npm:1.0.1" @@ -7822,6 +8862,14 @@ __metadata: languageName: node linkType: hard +"ini@npm:^1.3.4, ini@npm:^1.3.5, ini@npm:~1.3.0": +"ini@npm:2.0.0": + version: 2.0.0 + resolution: "ini@npm:2.0.0" + checksum: e7aadc5fb2e4aefc666d74ee2160c073995a4061556b1b5b4241ecb19ad609243b9cceafe91bae49c219519394bbd31512516cb22a3b1ca6e66d869e0447e84e + languageName: node + linkType: hard + "ini@npm:^1.3.4, ini@npm:^1.3.5, ini@npm:~1.3.0": version: 1.3.8 resolution: "ini@npm:1.3.8" @@ -7829,9 +8877,9 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:9.2.10": - version: 9.2.10 - resolution: "inquirer@npm:9.2.10" +"inquirer@npm:9.2.11": + version: 9.2.11 + resolution: "inquirer@npm:9.2.11" dependencies: "@ljharb/through": ^2.3.9 ansi-escapes: ^4.3.2 @@ -7848,7 +8896,7 @@ __metadata: string-width: ^4.2.3 strip-ansi: ^6.0.1 wrap-ansi: ^6.2.0 - checksum: 7ea6b3aff7a77d2b885f2dccf81736d46b15e1c8ead458b1725d468755e1be9b8c4bc2a8e9c9a4aa52a11b41c6b785696216915ee7090c94ee135e35973be19c + checksum: af59b422eb6005dac90f6c5e8295013d0611ac5471ff4fbf4ad3e228136e0f41db73af2d5a68e36770f9e31ac203ae1589d35c3e970acbc6110bb5df905928f9 languageName: node linkType: hard @@ -7873,6 +8921,7 @@ __metadata: languageName: node linkType: hard +"internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.5": "internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.5": version: 1.0.5 resolution: "internal-slot@npm:1.0.5" @@ -7907,6 +8956,13 @@ __metadata: languageName: node linkType: hard +"ip@npm:^1.1.8": + version: 1.1.8 + resolution: "ip@npm:1.1.8" + checksum: a2ade53eb339fb0cbe9e69a44caab10d6e3784662285eb5d2677117ee4facc33a64679051c35e0dfdb1a3983a51ce2f5d2cb36446d52e10d01881789b76e28fb + languageName: node + linkType: hard + "ip@npm:^2.0.0": version: 2.0.0 resolution: "ip@npm:2.0.0" @@ -7924,6 +8980,16 @@ __metadata: languageName: node linkType: hard +"is-arguments@npm:^1.1.1": + version: 1.1.1 + resolution: "is-arguments@npm:1.1.1" + dependencies: + call-bind: ^1.0.2 + has-tostringtag: ^1.0.0 + checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27 + languageName: node + linkType: hard + "is-array-buffer@npm:^3.0.1, is-array-buffer@npm:^3.0.2": version: 3.0.2 resolution: "is-array-buffer@npm:3.0.2" @@ -7995,12 +9061,27 @@ __metadata: languageName: node linkType: hard +"is-core-module@npm:^2.13.0": + version: 2.13.0 + resolution: "is-core-module@npm:2.13.0" +"is-ci@npm:3.0.1, is-ci@npm:^3.0.1": + version: 3.0.1 + resolution: "is-ci@npm:3.0.1" + dependencies: + ci-info: ^3.2.0 + bin: + is-ci: bin.js + checksum: 192c66dc7826d58f803ecae624860dccf1899fc1f3ac5505284c0a5cf5f889046ffeb958fa651e5725d5705c5bcb14f055b79150ea5fcad7456a9569de60260e + languageName: node + linkType: hard + "is-core-module@npm:^2.13.0": version: 2.13.0 resolution: "is-core-module@npm:2.13.0" dependencies: has: ^1.0.3 checksum: 053ab101fb390bfeb2333360fd131387bed54e476b26860dc7f5a700bbf34a0ec4454f7c8c4d43e8a0030957e4b3db6e16d35e1890ea6fb654c833095e040355 + checksum: 053ab101fb390bfeb2333360fd131387bed54e476b26860dc7f5a700bbf34a0ec4454f7c8c4d43e8a0030957e4b3db6e16d35e1890ea6fb654c833095e040355 languageName: node linkType: hard @@ -8031,6 +9112,15 @@ __metadata: languageName: node linkType: hard +"is-docker@npm:^3.0.0": + version: 3.0.0 + resolution: "is-docker@npm:3.0.0" + bin: + is-docker: cli.js + checksum: b698118f04feb7eaf3338922bd79cba064ea54a1c3db6ec8c0c8d8ee7613e7e5854d802d3ef646812a8a3ace81182a085dfa0a71cc68b06f3fa794b9783b3c90 + languageName: node + linkType: hard + "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -8103,6 +9193,41 @@ __metadata: languageName: node linkType: hard +"is-inside-container@npm:^1.0.0": + version: 1.0.0 + resolution: "is-inside-container@npm:1.0.0" + dependencies: + is-docker: ^3.0.0 + bin: + is-inside-container: cli.js + checksum: c50b75a2ab66ab3e8b92b3bc534e1ea72ca25766832c0623ac22d134116a98bcf012197d1caabe1d1c4bd5f84363d4aa5c36bb4b585fbcaf57be172cd10a1a03 + languageName: node + linkType: hard + +"is-installed-globally@npm:^0.4.0": + version: 0.4.0 + resolution: "is-installed-globally@npm:0.4.0" + dependencies: + global-dirs: ^3.0.0 + is-path-inside: ^3.0.2 + checksum: 3359840d5982d22e9b350034237b2cda2a12bac1b48a721912e1ab8e0631dd07d45a2797a120b7b87552759a65ba03e819f1bd63f2d7ab8657ec0b44ee0bf399 + languageName: node + linkType: hard + +"is-interactive@npm:^1.0.0": + version: 1.0.0 + resolution: "is-interactive@npm:1.0.0" + checksum: 824808776e2d468b2916cdd6c16acacebce060d844c35ca6d82267da692e92c3a16fdba624c50b54a63f38bdc4016055b6f443ce57d7147240de4f8cdabaf6f9 + languageName: node + linkType: hard + +"is-interactive@npm:^2.0.0": + version: 2.0.0 + resolution: "is-interactive@npm:2.0.0" + checksum: e8d52ad490bed7ae665032c7675ec07732bbfe25808b0efbc4d5a76b1a1f01c165f332775c63e25e9a03d319ebb6b24f571a9e902669fc1e40b0a60b5be6e26c + languageName: node + linkType: hard + "is-lambda@npm:^1.0.1": version: 1.0.1 resolution: "is-lambda@npm:1.0.1" @@ -8117,6 +9242,13 @@ __metadata: languageName: node linkType: hard +"is-map@npm:^2.0.2": + version: 2.0.2 + resolution: "is-map@npm:2.0.2" + checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 + languageName: node + linkType: hard + "is-negative-zero@npm:^2.0.2": version: 2.0.2 resolution: "is-negative-zero@npm:2.0.2" @@ -8131,6 +9263,13 @@ __metadata: languageName: node linkType: hard +"is-npm@npm:^6.0.0": + version: 6.0.0 + resolution: "is-npm@npm:6.0.0" + checksum: fafe1ddc772345f5460514891bb8014376904ccdbddd59eee7525c9adcc08d426933f28b087bef3e17524da7ebf35c03ef484ff3b6ba9d5fecd8c6e6a7d4bf11 + languageName: node + linkType: hard + "is-number-object@npm:^1.0.4": version: 1.0.7 resolution: "is-number-object@npm:1.0.7" @@ -8154,6 +9293,14 @@ __metadata: languageName: node linkType: hard +"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": +"is-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "is-obj@npm:2.0.0" + checksum: c9916ac8f4621962a42f5e80e7ffdb1d79a3fab7456ceaeea394cd9e0858d04f985a9ace45be44433bf605673c8be8810540fe4cc7f4266fc7526ced95af5a08 + languageName: node + linkType: hard + "is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" @@ -8175,6 +9322,13 @@ __metadata: languageName: node linkType: hard +"is-plain-object@npm:^5.0.0": + version: 5.0.0 + resolution: "is-plain-object@npm:5.0.0" + checksum: e32d27061eef62c0847d303125440a38660517e586f2f3db7c9d179ae5b6674ab0f469d519b2e25c147a1a3bc87156d0d5f4d8821e0ce4a9ee7fe1fcf11ce45c + languageName: node + linkType: hard + "is-regex@npm:^1.1.4": version: 1.1.4 resolution: "is-regex@npm:1.1.4" @@ -8192,6 +9346,13 @@ __metadata: languageName: node linkType: hard +"is-set@npm:^2.0.2": + version: 2.0.2 + resolution: "is-set@npm:2.0.2" + checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 + languageName: node + linkType: hard + "is-shared-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "is-shared-array-buffer@npm:1.0.2" @@ -8210,6 +9371,15 @@ __metadata: languageName: node linkType: hard +"is-ssh@npm:^1.4.0": + version: 1.4.0 + resolution: "is-ssh@npm:1.4.0" + dependencies: + protocols: ^2.0.1 + checksum: 75eaa17b538bee24b661fbeb0f140226ac77e904a6039f787bea418431e2162f1f9c4c4ccad3bd169e036cd701cc631406e8c505d9fa7e20164e74b47f86f40f + languageName: node + linkType: hard + "is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" @@ -8231,6 +9401,13 @@ __metadata: languageName: node linkType: hard +"is-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "is-stream@npm:3.0.0" + checksum: 172093fe99119ffd07611ab6d1bcccfe8bc4aa80d864b15f43e63e54b7abc71e779acd69afdb854c4e2a67fdc16ae710e370eda40088d1cfc956a50ed82d8f16 + languageName: node + linkType: hard + "is-string@npm:^1.0.5, is-string@npm:^1.0.7": version: 1.0.7 resolution: "is-string@npm:1.0.7" @@ -8249,7 +9426,7 @@ __metadata: languageName: node linkType: hard -"is-typed-array@npm:^1.1.10, is-typed-array@npm:^1.1.9": +"is-typed-array@npm:^1.1.10, is-typed-array@npm:^1.1.12, is-typed-array@npm:^1.1.9": version: 1.1.12 resolution: "is-typed-array@npm:1.1.12" dependencies: @@ -8258,6 +9435,7 @@ __metadata: languageName: node linkType: hard +"is-typedarray@npm:^1.0.0, is-typedarray@npm:~1.0.0": "is-typedarray@npm:^1.0.0, is-typedarray@npm:~1.0.0": version: 1.0.0 resolution: "is-typedarray@npm:1.0.0" @@ -8279,6 +9457,13 @@ __metadata: languageName: node linkType: hard +"is-unicode-supported@npm:^1.1.0, is-unicode-supported@npm:^1.2.0, is-unicode-supported@npm:^1.3.0": + version: 1.3.0 + resolution: "is-unicode-supported@npm:1.3.0" + checksum: 20a1fc161afafaf49243551a5ac33b6c4cf0bbcce369fcd8f2951fbdd000c30698ce320de3ee6830497310a8f41880f8066d440aa3eb0a853e2aa4836dd89abc + languageName: node + linkType: hard + "is-weakref@npm:^1.0.2": version: 1.0.2 resolution: "is-weakref@npm:1.0.2" @@ -8304,6 +9489,13 @@ __metadata: languageName: node linkType: hard +"is-yarn-global@npm:^0.4.0": + version: 0.4.1 + resolution: "is-yarn-global@npm:0.4.1" + checksum: 79ec4e6f581c53d4fefdf5f6c237f9a3ad8db29c85cdc4659e76ae345659317552052a97b7e56952aa5d94a23c798ebec8ccad72fb14d3b26dc647ddceddd716 + languageName: node + linkType: hard + "isarray@npm:^1.0.0, isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" @@ -8355,6 +9547,19 @@ __metadata: languageName: node linkType: hard +"issue-parser@npm:6.0.0": + version: 6.0.0 + resolution: "issue-parser@npm:6.0.0" + dependencies: + lodash.capitalize: ^4.2.1 + lodash.escaperegexp: ^4.1.2 + lodash.isplainobject: ^4.0.6 + lodash.isstring: ^4.0.1 + lodash.uniqby: ^4.7.0 + checksum: 3357928af6c78c4803340f978bd55dc922b6b15b3f6c76aaa78a08999d39002729502ce1650863d1a9d728a7e31ccc0a865087244225ef6e8fc85aaf2f9c0f67 + languageName: node + linkType: hard + "istanbul-combine@npm:^0.3.0": version: 0.3.0 resolution: "istanbul-combine@npm:0.3.0" @@ -8410,16 +9615,16 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.0.3": - version: 2.3.0 - resolution: "jackspeak@npm:2.3.0" +"jackspeak@npm:^2.3.5": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" dependencies: "@isaacs/cliui": ^8.0.2 "@pkgjs/parseargs": ^0.11.0 dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 71bf716f4b5793226d4aeb9761ebf2605ee093b59f91a61451d57d998dd64bbf2b54323fb749b8b2ae8b6d8a463de4f6e3fedab50108671f247bbc80195a6306 + checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 languageName: node linkType: hard @@ -8437,13 +9642,6 @@ __metadata: languageName: node linkType: hard -"js-sha3@npm:0.5.7": - version: 0.5.7 - resolution: "js-sha3@npm:0.5.7" - checksum: 973a28ea4b26cc7f12d2ab24f796e24ee4a71eef45a6634a052f6eb38cf8b2333db798e896e6e094ea6fa4dfe8e42a2a7942b425cf40da3f866623fd05bb91ea - languageName: node - linkType: hard - "js-sha3@npm:0.8.0, js-sha3@npm:^0.8.0": version: 0.8.0 resolution: "js-sha3@npm:0.8.0" @@ -8527,6 +9725,13 @@ __metadata: languageName: node linkType: hard +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 9026b03edc2847eefa2e37646c579300a1f3a4586cfb62bf857832b60c852042d0d6ae55d1afb8926163fa54c2b01d83ae24705f34990348bdac6273a29d4581 + languageName: node + linkType: hard + "json-parse-even-better-errors@npm:^2.3.0": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" @@ -8672,14 +9877,14 @@ __metadata: linkType: hard "keccak@npm:^3.0.0, keccak@npm:^3.0.2": - version: 3.0.3 - resolution: "keccak@npm:3.0.3" + version: 3.0.4 + resolution: "keccak@npm:3.0.4" dependencies: node-addon-api: ^2.0.0 node-gyp: latest node-gyp-build: ^4.2.0 readable-stream: ^3.6.0 - checksum: f08f04f5cc87013a3fc9e87262f761daff38945c86dd09c01a7f7930a15ae3e14f93b310ef821dcc83675a7b814eb1c983222399a2f263ad980251201d1b9a99 + checksum: 2bf27b97b2f24225b1b44027de62be547f5c7326d87d249605665abd0c8c599d774671c35504c62c9b922cae02758504c6f76a73a84234d23af8a2211afaaa11 languageName: node linkType: hard @@ -8720,6 +9925,15 @@ __metadata: languageName: node linkType: hard +"latest-version@npm:^7.0.0": + version: 7.0.0 + resolution: "latest-version@npm:7.0.0" + dependencies: + package-json: ^8.1.0 + checksum: 1f0deba00d5a34394cce4463c938811f51bbb539b131674f4bb2062c63f2cc3b80bccd56ecade3bd5932d04a34cf0a5a8a2ccc4ec9e5e6b285a9a7b3e27d0d66 + languageName: node + linkType: hard + "level-codec@npm:^9.0.0": version: 9.0.2 resolution: "level-codec@npm:9.0.2" @@ -8923,6 +10137,13 @@ __metadata: languageName: node linkType: hard +"lodash.capitalize@npm:^4.2.1": + version: 4.2.1 + resolution: "lodash.capitalize@npm:4.2.1" + checksum: d9195f31d48c105206f1099946d8bbc8ab71435bc1c8708296992a31a992bb901baf120fdcadd773098ac96e62a79e6b023ee7d26a2deb0d6c6aada930e6ad0a + languageName: node + linkType: hard + "lodash.clonedeep@npm:^4.5.0": version: 4.5.0 resolution: "lodash.clonedeep@npm:4.5.0" @@ -8937,6 +10158,13 @@ __metadata: languageName: node linkType: hard +"lodash.escaperegexp@npm:^4.1.2": + version: 4.1.2 + resolution: "lodash.escaperegexp@npm:4.1.2" + checksum: 6d99452b1cfd6073175a9b741a9b09ece159eac463f86f02ea3bee2e2092923fce812c8d2bf446309cc52d1d61bf9af51c8118b0d7421388e6cead7bd3798f0f + languageName: node + linkType: hard + "lodash.isequal@npm:^4.5.0": version: 4.5.0 resolution: "lodash.isequal@npm:4.5.0" @@ -8958,6 +10186,20 @@ __metadata: languageName: node linkType: hard +"lodash.isplainobject@npm:^4.0.6": + version: 4.0.6 + resolution: "lodash.isplainobject@npm:4.0.6" + checksum: 29c6351f281e0d9a1d58f1a4c8f4400924b4c79f18dfc4613624d7d54784df07efaff97c1ff2659f3e085ecf4fff493300adc4837553104cef2634110b0d5337 + languageName: node + linkType: hard + +"lodash.isstring@npm:^4.0.1": + version: 4.0.1 + resolution: "lodash.isstring@npm:4.0.1" + checksum: eaac87ae9636848af08021083d796e2eea3d02e80082ab8a9955309569cb3a463ce97fd281d7dc119e402b2e7d8c54a23914b15d2fc7fff56461511dc8937ba0 + languageName: node + linkType: hard + "lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -8979,6 +10221,14 @@ __metadata: languageName: node linkType: hard +"lodash@npm:4.17.21, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.21": +"lodash.uniqby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.uniqby@npm:4.7.0" + checksum: 659264545a95726d1493123345aad8cbf56e17810fa9a0b029852c6d42bc80517696af09d99b23bef1845d10d95e01b8b4a1da578f22aeba7a30d3e0022a4938 + languageName: node + linkType: hard + "lodash@npm:4.17.21, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" @@ -9004,6 +10254,7 @@ __metadata: languageName: node linkType: hard +"log-symbols@npm:4.1.0, log-symbols@npm:^4.1.0": "log-symbols@npm:4.1.0, log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" @@ -9024,7 +10275,7 @@ __metadata: languageName: node linkType: hard -"loupe@npm:^2.3.1": +"loupe@npm:^2.3.6": version: 2.3.6 resolution: "loupe@npm:2.3.6" dependencies: @@ -9040,6 +10291,13 @@ __metadata: languageName: node linkType: hard +"lowercase-keys@npm:^3.0.0": + version: 3.0.0 + resolution: "lowercase-keys@npm:3.0.0" + checksum: 67a3f81409af969bc0c4ca0e76cd7d16adb1e25aa1c197229587eaf8671275c8c067cd421795dbca4c81be0098e4c426a086a05e30de8a9c587b7a13c0c7ccc5 + languageName: node + linkType: hard + "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -9058,6 +10316,7 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^7.14.1, lru-cache@npm:^7.7.1": "lru-cache@npm:^7.14.1, lru-cache@npm:^7.7.1": version: 7.18.3 resolution: "lru-cache@npm:7.18.3" @@ -9066,6 +10325,9 @@ __metadata: linkType: hard "lru-cache@npm:^9.1.1 || ^10.0.0": + version: 10.0.1 + resolution: "lru-cache@npm:10.0.1" + checksum: 06f8d0e1ceabd76bb6f644a26dbb0b4c471b79c7b514c13c6856113879b3bf369eb7b497dad4ff2b7e2636db202412394865b33c332100876d838ad1372f0181 version: 10.0.1 resolution: "lru-cache@npm:10.0.1" checksum: 06f8d0e1ceabd76bb6f644a26dbb0b4c471b79c7b514c13c6856113879b3bf369eb7b497dad4ff2b7e2636db202412394865b33c332100876d838ad1372f0181 @@ -9093,6 +10355,13 @@ __metadata: languageName: node linkType: hard +"macos-release@npm:^3.1.0": + version: 3.2.0 + resolution: "macos-release@npm:3.2.0" + checksum: e780af4a8dcfdb4d7b5e717f866baf19f81798772b1f422ca5409c0a6b39baeb80827976fa498b8582409100c2d8c10cb89498dd557d777218cb40733c771843 + languageName: node + linkType: hard + "make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" @@ -9219,6 +10488,13 @@ __metadata: languageName: node linkType: hard +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + "merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 resolution: "merge2@npm:1.4.1" @@ -9247,6 +10523,13 @@ __metadata: languageName: node linkType: hard +"micro-ftch@npm:^0.3.1": + version: 0.3.1 + resolution: "micro-ftch@npm:0.3.1" + checksum: 0e496547253a36e98a83fb00c628c53c3fb540fa5aaeaf718438873785afd193244988c09d219bb1802984ff227d04938d9571ef90fe82b48bd282262586aaff + languageName: node + linkType: hard + "micromatch@npm:^4.0.4": version: 4.0.5 resolution: "micromatch@npm:4.0.5" @@ -9264,6 +10547,7 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:~2.1.19": "mime-types@npm:2.1.35, mime-types@npm:^2.1.12, mime-types@npm:~2.1.19": version: 2.1.35 resolution: "mime-types@npm:2.1.35" @@ -9301,6 +10585,27 @@ __metadata: languageName: node linkType: hard +"mimic-fn@npm:^4.0.0": + version: 4.0.0 + resolution: "mimic-fn@npm:4.0.0" + checksum: 995dcece15ee29aa16e188de6633d43a3db4611bcf93620e7e62109ec41c79c0f34277165b8ce5e361205049766e371851264c21ac64ca35499acb5421c2ba56 + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 25739fee32c17f433626bf19f016df9036b75b3d84a3046c7d156e72ec963dd29d7fc8a302f55a3d6c5a4ff24259676b15d915aad6480815a969ff2ec0836867 + languageName: node + linkType: hard + +"mimic-response@npm:^4.0.0": + version: 4.0.0 + resolution: "mimic-response@npm:4.0.0" + checksum: 33b804cc961efe206efdb1fca6a22540decdcfce6c14eb5c0c50e5ae9022267ab22ce8f5568b1f7247ba67500fe20d523d81e0e9f009b321ccd9d472e78d1850 + languageName: node + linkType: hard + "minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" @@ -9387,7 +10692,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.1.1, minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6": +"minimist@npm:^1.1.1, minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.7": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -9404,17 +10709,21 @@ __metadata: linkType: hard "minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" version: 3.0.4 resolution: "minipass-fetch@npm:3.0.4" dependencies: encoding: ^0.1.13 minipass: ^7.0.3 + minipass: ^7.0.3 minipass-sized: ^1.0.3 minizlib: ^2.1.2 dependenciesMeta: encoding: optional: true checksum: af7aad15d5c128ab1ebe52e043bdf7d62c3c6f0cecb9285b40d7b395e1375b45dcdfd40e63e93d26a0e8249c9efd5c325c65575aceee192883970ff8cb11364a + checksum: af7aad15d5c128ab1ebe52e043bdf7d62c3c6f0cecb9285b40d7b395e1375b45dcdfd40e63e93d26a0e8249c9efd5c325c65575aceee192883970ff8cb11364a languageName: node linkType: hard @@ -9469,9 +10778,9 @@ __metadata: linkType: hard "minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.3": - version: 7.0.3 - resolution: "minipass@npm:7.0.3" - checksum: 6f1614f5b5b55568a46bca5fec0e7c46dac027691db27d0e1923a8192866903144cd962ac772c0e9f89b608ea818b702709c042bce98e190d258847d85461531 + version: 7.0.4 + resolution: "minipass@npm:7.0.4" + checksum: 87585e258b9488caf2e7acea242fd7856bbe9a2c84a7807643513a338d66f368c7d518200ad7b70a508664d408aa000517647b2930c259a8b1f9f0984f344a21 languageName: node linkType: hard @@ -9532,42 +10841,7 @@ __metadata: languageName: node linkType: hard -"mocha@npm:7.1.2": - version: 7.1.2 - resolution: "mocha@npm:7.1.2" - dependencies: - ansi-colors: 3.2.3 - browser-stdout: 1.3.1 - chokidar: 3.3.0 - debug: 3.2.6 - diff: 3.5.0 - escape-string-regexp: 1.0.5 - find-up: 3.0.0 - glob: 7.1.3 - growl: 1.10.5 - he: 1.2.0 - js-yaml: 3.13.1 - log-symbols: 3.0.0 - minimatch: 3.0.4 - mkdirp: 0.5.5 - ms: 2.1.1 - node-environment-flags: 1.0.6 - object.assign: 4.1.0 - strip-json-comments: 2.0.1 - supports-color: 6.0.0 - which: 1.3.1 - wide-align: 1.1.3 - yargs: 13.3.2 - yargs-parser: 13.1.2 - yargs-unparser: 1.6.0 - bin: - _mocha: bin/_mocha - mocha: bin/mocha - checksum: 0fc9ad0dd79e43a34de03441634f58e8a3d211af4cdbcd56de150ec99f7aff3b8678bd5aeb41f82115f7df4199a24f7bb372f65e5bcba133b41a5310dee908bd - languageName: node - linkType: hard - -"mocha@npm:^10.0.0": +"mocha@npm:10.2.0, mocha@npm:^10.0.0, mocha@npm:^10.2.0": version: 10.2.0 resolution: "mocha@npm:10.2.0" dependencies: @@ -9599,9 +10873,9 @@ __metadata: languageName: node linkType: hard -"mocha@npm:^7.1.1": - version: 7.2.0 - resolution: "mocha@npm:7.2.0" +"mocha@npm:7.1.2": + version: 7.1.2 + resolution: "mocha@npm:7.1.2" dependencies: ansi-colors: 3.2.3 browser-stdout: 1.3.1 @@ -9630,7 +10904,7 @@ __metadata: bin: _mocha: bin/_mocha mocha: bin/mocha - checksum: d098484fe1b165bb964fdbf6b88b256c71fead47575ca7c5bcf8ed07db0dcff41905f6d2f0a05111a0441efaef9d09241a8cc1ddf7961056b28984ec63ba2874 + checksum: 0fc9ad0dd79e43a34de03441634f58e8a3d211af4cdbcd56de150ec99f7aff3b8678bd5aeb41f82115f7df4199a24f7bb372f65e5bcba133b41a5310dee908bd languageName: node linkType: hard @@ -9730,6 +11004,13 @@ __metadata: languageName: node linkType: hard +"mute-stream@npm:1.0.0": + version: 1.0.0 + resolution: "mute-stream@npm:1.0.0" + checksum: 36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7 + languageName: node + linkType: hard + "nanoid@npm:3.1.20": version: 3.1.20 resolution: "nanoid@npm:3.1.20" @@ -9799,6 +11080,22 @@ __metadata: languageName: node linkType: hard +"netmask@npm:^2.0.2": + version: 2.0.2 + resolution: "netmask@npm:2.0.2" + checksum: c65cb8d3f7ea5669edddb3217e4c96910a60d0d9a4b52d9847ff6b28b2d0277cd8464eee0ef85133cdee32605c57940cacdd04a9a019079b091b6bba4cb0ec22 + languageName: node + linkType: hard + +"new-github-release-url@npm:2.0.0": + version: 2.0.0 + resolution: "new-github-release-url@npm:2.0.0" + dependencies: + type-fest: ^2.5.1 + checksum: 3d4ae0f3b775623ceed8e558b6f9850e897aea981a9c937d3ad4e018669c829beccb2c4b5a6af996726ebf86c5b7638368dfc01f3ac2e395d1df29309bc0c5ca + languageName: node + linkType: hard + "nice-try@npm:^1.0.4": version: 1.0.5 resolution: "nice-try@npm:1.0.5" @@ -9831,6 +11128,13 @@ __metadata: languageName: node linkType: hard +"node-domexception@npm:^1.0.0": + version: 1.0.0 + resolution: "node-domexception@npm:1.0.0" + checksum: ee1d37dd2a4eb26a8a92cd6b64dfc29caec72bff5e1ed9aba80c294f57a31ba4895a60fd48347cf17dd6e766da0ae87d75657dfd1f384ebfa60462c2283f5c7f + languageName: node + linkType: hard + "node-emoji@npm:^1.10.0, node-emoji@npm:^1.4.1": version: 1.11.0 resolution: "node-emoji@npm:1.11.0" @@ -9861,7 +11165,20 @@ __metadata: languageName: node linkType: hard +"node-fetch@npm:3.3.2": + version: 3.3.2 + resolution: "node-fetch@npm:3.3.2" + dependencies: + data-uri-to-buffer: ^4.0.0 + fetch-blob: ^3.1.4 + formdata-polyfill: ^4.0.10 + checksum: 06a04095a2ddf05b0830a0d5302699704d59bda3102894ea64c7b9d4c865ecdff2d90fd042df7f5bc40337266961cb6183dcc808ea4f3000d024f422b462da92 + languageName: node + linkType: hard + "node-fetch@npm:^2.6.0, node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.7": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -9872,6 +11189,7 @@ __metadata: encoding: optional: true checksum: d76d2f5edb451a3f05b15115ec89fc6be39de37c6089f1b6368df03b91e1633fd379a7e01b7ab05089a25034b2023d959b47e59759cb38d88341b2459e89d6e5 + checksum: d76d2f5edb451a3f05b15115ec89fc6be39de37c6089f1b6368df03b91e1633fd379a7e01b7ab05089a25034b2023d959b47e59759cb38d88341b2459e89d6e5 languageName: node linkType: hard @@ -9883,6 +11201,8 @@ __metadata: linkType: hard "node-gyp-build@npm:^4.2.0, node-gyp-build@npm:^4.3.0": + version: 4.6.1 + resolution: "node-gyp-build@npm:4.6.1" version: 4.6.1 resolution: "node-gyp-build@npm:4.6.1" bin: @@ -9890,6 +11210,7 @@ __metadata: node-gyp-build-optional: optional.js node-gyp-build-test: build-test.js checksum: c3676d337b36803bc7792e35bf7fdcda7cdcb7e289b8f9855a5535702a82498eb976842fefcf487258c58005ca32ce3d537fbed91280b04409161dcd7232a882 + checksum: c3676d337b36803bc7792e35bf7fdcda7cdcb7e289b8f9855a5535702a82498eb976842fefcf487258c58005ca32ce3d537fbed91280b04409161dcd7232a882 languageName: node linkType: hard @@ -9957,6 +11278,13 @@ __metadata: languageName: node linkType: hard +"normalize-url@npm:^8.0.0": + version: 8.0.0 + resolution: "normalize-url@npm:8.0.0" + checksum: 24c20b75ebfd526d8453084692720b49d111c63c0911f1b7447427829597841eef5a8ba3f6bb93d6654007b991c1f5cd85da2c907800e439e2e2ec6c2abd0fc0 + languageName: node + linkType: hard + "npm-run-path@npm:^2.0.0": version: 2.0.2 resolution: "npm-run-path@npm:2.0.2" @@ -9984,6 +11312,15 @@ __metadata: languageName: node linkType: hard +"npm-run-path@npm:^5.1.0": + version: 5.1.0 + resolution: "npm-run-path@npm:5.1.0" + dependencies: + path-key: ^4.0.0 + checksum: dc184eb5ec239d6a2b990b43236845332ef12f4e0beaa9701de724aa797fe40b6bbd0157fb7639d24d3ab13f5d5cf22d223a19c6300846b8126f335f788bee66 + languageName: node + linkType: hard + "npmlog@npm:^6.0.0": version: 6.0.2 resolution: "npmlog@npm:6.0.2" @@ -10140,15 +11477,15 @@ __metadata: linkType: hard "object.getownpropertydescriptors@npm:^2.0.3": - version: 2.1.6 - resolution: "object.getownpropertydescriptors@npm:2.1.6" + version: 2.1.7 + resolution: "object.getownpropertydescriptors@npm:2.1.7" dependencies: - array.prototype.reduce: ^1.0.5 + array.prototype.reduce: ^1.0.6 call-bind: ^1.0.2 define-properties: ^1.2.0 - es-abstract: ^1.21.2 + es-abstract: ^1.22.1 safe-array-concat: ^1.0.0 - checksum: 7757ce0ef61c8bee7f8043f8980fd3d46fc1ab3faf0795bd1f9f836781143b4afc91f7219a3eed4675fbd0b562f3708f7e736d679ebfd43ea37ab6077d9f5004 + checksum: 8e7ae1d522a3874d2d23a3d0fb75828cbcee60958b65c2ad8e58ce227f4efba8cc2b59c7431a0fd48b20d9e04ec075bc0e0d694b1d2c2296e534daf558beb10b languageName: node linkType: hard @@ -10177,6 +11514,7 @@ __metadata: languageName: node linkType: hard +"onetime@npm:^5.1.0, onetime@npm:^5.1.2": "onetime@npm:^5.1.0, onetime@npm:^5.1.2": version: 5.1.2 resolution: "onetime@npm:5.1.2" @@ -10207,6 +11545,27 @@ __metadata: languageName: node linkType: hard +"onetime@npm:^6.0.0": + version: 6.0.0 + resolution: "onetime@npm:6.0.0" + dependencies: + mimic-fn: ^4.0.0 + checksum: 0846ce78e440841335d4e9182ef69d5762e9f38aa7499b19f42ea1c4cd40f0b4446094c455c713f9adac3f4ae86f613bb5e30c99e52652764d06a89f709b3788 + languageName: node + linkType: hard + +"open@npm:9.1.0": + version: 9.1.0 + resolution: "open@npm:9.1.0" + dependencies: + default-browser: ^4.0.0 + define-lazy-prop: ^3.0.0 + is-inside-container: ^1.0.0 + is-wsl: ^2.2.0 + checksum: 3993c0f61d51fed8ac290e99c9c3cf45d3b6cfb3e2aa2b74cafd312c3486c22fd81df16ac8f3ab91dd8a4e3e729a16fc2480cfc406c4833416cf908acf1ae7c9 + languageName: node + linkType: hard + "open@npm:^8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" @@ -10218,7 +11577,7 @@ __metadata: languageName: node linkType: hard -"operator-filter-registry@npm:^1.3.1": +"operator-filter-registry@npm:^1.3.1, operator-filter-registry@npm:^1.4.2": version: 1.4.2 resolution: "operator-filter-registry@npm:1.4.2" dependencies: @@ -10304,6 +11663,40 @@ __metadata: languageName: node linkType: hard +"ora@npm:7.0.1": + version: 7.0.1 + resolution: "ora@npm:7.0.1" + dependencies: + chalk: ^5.3.0 + cli-cursor: ^4.0.0 + cli-spinners: ^2.9.0 + is-interactive: ^2.0.0 + is-unicode-supported: ^1.3.0 + log-symbols: ^5.1.0 + stdin-discarder: ^0.1.0 + string-width: ^6.1.0 + strip-ansi: ^7.1.0 + checksum: 0842b8b9a96a8586085cafdc25077c76fed8ade072c52c53e748cf40a214731d2215a4d6081d8fbd6203d2b897e834332bda53eb64afd1a5968da17daf020bff + languageName: node + linkType: hard + +"ora@npm:^5.4.1": + version: 5.4.1 + resolution: "ora@npm:5.4.1" + dependencies: + bl: ^4.1.0 + chalk: ^4.1.0 + cli-cursor: ^3.1.0 + cli-spinners: ^2.5.0 + is-interactive: ^1.0.0 + is-unicode-supported: ^0.1.0 + log-symbols: ^4.1.0 + strip-ansi: ^6.0.0 + wcwidth: ^1.0.1 + checksum: 28d476ee6c1049d68368c0dc922e7225e3b5600c3ede88fade8052837f9ed342625fdaa84a6209302587c8ddd9b664f71f0759833cbdb3a4cf81344057e63c63 + languageName: node + linkType: hard + "ordinal@npm:^1.0.3": version: 1.0.3 resolution: "ordinal@npm:1.0.3" @@ -10321,6 +11714,16 @@ __metadata: languageName: node linkType: hard +"os-name@npm:5.1.0": + version: 5.1.0 + resolution: "os-name@npm:5.1.0" + dependencies: + macos-release: ^3.1.0 + windows-release: ^5.0.1 + checksum: fae0fc02601d2966ee3255e80a6b3ac5d04265228d7b08563b4a8f2057732250cdff80b7ec33de2fef565cd92104078e71f4959fc081c6d197e2ec03a760ca42 + languageName: node + linkType: hard + "os-tmpdir@npm:~1.0.2": version: 1.0.2 resolution: "os-tmpdir@npm:1.0.2" @@ -10335,6 +11738,13 @@ __metadata: languageName: node linkType: hard +"p-cancelable@npm:^3.0.0": + version: 3.0.0 + resolution: "p-cancelable@npm:3.0.0" + checksum: 2b5ae34218f9c2cf7a7c18e5d9a726ef9b165ef07e6c959f6738371509e747334b5f78f3bcdeb03d8a12dcb978faf641fd87eb21486ed7d36fb823b8ddef3219 + languageName: node + linkType: hard + "p-finally@npm:^1.0.0": version: 1.0.0 resolution: "p-finally@npm:1.0.0" @@ -10419,19 +11829,19 @@ __metadata: languageName: node linkType: hard -"pac-proxy-agent@npm:^7.0.0": - version: 7.0.0 - resolution: "pac-proxy-agent@npm:7.0.0" +"pac-proxy-agent@npm:^7.0.1": + version: 7.0.1 + resolution: "pac-proxy-agent@npm:7.0.1" dependencies: "@tootallnate/quickjs-emscripten": ^0.23.0 agent-base: ^7.0.2 debug: ^4.3.4 get-uri: ^6.0.1 http-proxy-agent: ^7.0.0 - https-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.2 pac-resolver: ^7.0.0 - socks-proxy-agent: ^8.0.1 - checksum: 45fe10ae58b1700d5419a9e5b525fb261b866ed6a65c1382fe45c3d5af9f81d9a58250d407941a363b1955e0315f3d97e02a2f20e4c7e2ba793bd46585db7ec8 + socks-proxy-agent: ^8.0.2 + checksum: 3d4aa48ec1c19db10158ecc1c4c9a9f77792294412d225ceb3dfa45d5a06950dca9755e2db0d9b69f12769119bea0adf2b24390d9c73c8d81df75e28245ae451 languageName: node linkType: hard @@ -10474,7 +11884,7 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^5.0.0": +"parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" dependencies: @@ -10504,6 +11914,24 @@ __metadata: languageName: node linkType: hard +"parse-path@npm:^7.0.0": + version: 7.0.0 + resolution: "parse-path@npm:7.0.0" + dependencies: + protocols: ^2.0.0 + checksum: 244b46523a58181d251dda9b888efde35d8afb957436598d948852f416d8c76ddb4f2010f9fc94218b4be3e5c0f716aa0d2026194a781e3b8981924142009302 + languageName: node + linkType: hard + +"parse-url@npm:^8.1.0": + version: 8.1.0 + resolution: "parse-url@npm:8.1.0" + dependencies: + parse-path: ^7.0.0 + checksum: b93e21ab4c93c7d7317df23507b41be7697694d4c94f49ed5c8d6288b01cba328fcef5ba388e147948eac20453dee0df9a67ab2012415189fff85973bdffe8d9 + languageName: node + linkType: hard + "path-exists@npm:^3.0.0": version: 3.0.0 resolution: "path-exists@npm:3.0.0" @@ -10546,6 +11974,13 @@ __metadata: languageName: node linkType: hard +"path-key@npm:^4.0.0": + version: 4.0.0 + resolution: "path-key@npm:4.0.0" + checksum: 8e6c314ae6d16b83e93032c61020129f6f4484590a777eed709c4a01b50e498822b00f76ceaf94bc64dbd90b327df56ceadce27da3d83393790f1219e07721d7 + languageName: node + linkType: hard + "path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" @@ -10719,17 +12154,17 @@ __metadata: languageName: node linkType: hard -"promise.allsettled@npm:1.0.6": - version: 1.0.6 - resolution: "promise.allsettled@npm:1.0.6" +"promise.allsettled@npm:1.0.7": + version: 1.0.7 + resolution: "promise.allsettled@npm:1.0.7" dependencies: array.prototype.map: ^1.0.5 call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - get-intrinsic: ^1.1.3 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + get-intrinsic: ^1.2.1 iterate-value: ^1.0.2 - checksum: 5de80c33f41b23387be49229e47ade2fbeb86ad9b2066e5e093c21dbd5a3e7a8e4eb8e420cbf58386e2af976cc4677950092f855b677b16771191599f493d035 + checksum: 96186392286e5ab9aef1a1a725c061c8cf268b6cf141f151daa3834bb8e1680f3b159af6536ce59cf80d4a6a5ad1d8371d05759980cc6c90d58800ddb0a7c119 languageName: node linkType: hard @@ -10742,6 +12177,17 @@ __metadata: languageName: node linkType: hard +"proper-lockfile@npm:^4.1.1": + version: 4.1.2 + resolution: "proper-lockfile@npm:4.1.2" + dependencies: + graceful-fs: ^4.2.4 + retry: ^0.12.0 + signal-exit: ^3.0.2 + checksum: 00078ee6a61c216a56a6140c7d2a98c6c733b3678503002dc073ab8beca5d50ca271de4c85fca13b9b8ee2ff546c36674d1850509b84a04a5d0363bcb8638939 + languageName: node + linkType: hard + "proto-list@npm:~1.2.1": version: 1.2.4 resolution: "proto-list@npm:1.2.4" @@ -10756,19 +12202,19 @@ __metadata: languageName: node linkType: hard -"proxy-agent@npm:6.3.0": - version: 6.3.0 - resolution: "proxy-agent@npm:6.3.0" +"proxy-agent@npm:6.3.1": + version: 6.3.1 + resolution: "proxy-agent@npm:6.3.1" dependencies: agent-base: ^7.0.2 debug: ^4.3.4 http-proxy-agent: ^7.0.0 - https-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.2 lru-cache: ^7.14.1 - pac-proxy-agent: ^7.0.0 + pac-proxy-agent: ^7.0.1 proxy-from-env: ^1.1.0 - socks-proxy-agent: ^8.0.1 - checksum: e3fb0633d665e352ed4efe23ae5616b8301423dfa4ff1c5975d093da8a636181a97391f7a91c6a7ffae17c1a305df855e95507f73bcdafda8876198c64b88f5b + socks-proxy-agent: ^8.0.2 + checksum: 31030da419da31809340ac2521090c9a5bf4fe47a944843f829b3502883208c8586a468955e64b694140a41d70af6f45cf4793f5efd4a6f3ed94e5ac8023e36d languageName: node linkType: hard @@ -10819,6 +12265,15 @@ __metadata: languageName: node linkType: hard +"pupa@npm:^3.1.0": + version: 3.1.0 + resolution: "pupa@npm:3.1.0" + dependencies: + escape-goat: ^4.0.0 + checksum: 0e4f4ab6bbdce600fa6d23b1833f1af57b2641246ff4cbe10f9d66e4e5479b0de2864a88d5bd629eef59524eda3c6680726acd7f3f873d9ed46b7f095d0bb5f6 + languageName: node + linkType: hard + "q@npm:^1.2.0": version: 1.5.1 resolution: "q@npm:1.5.1" @@ -10856,7 +12311,7 @@ __metadata: languageName: node linkType: hard -"rambda@npm:^7.1.0": +"rambda@npm:^7.4.0": version: 7.5.0 resolution: "rambda@npm:7.5.0" checksum: ad608a9a4160d0b6b0921047cea1329276bf239ff58d439135288712dcdbbf0df47c76591843ad249d89e7c5a9109ce86fe099aa54aef0dc0aa92a9b4dd1b8eb @@ -10905,6 +12360,20 @@ __metadata: languageName: node linkType: hard +"rc@npm:1.2.8": + version: 1.2.8 + resolution: "rc@npm:1.2.8" + dependencies: + deep-extend: ^0.6.0 + ini: ~1.3.0 + minimist: ^1.2.0 + strip-json-comments: ~2.0.1 + bin: + rc: ./cli.js + checksum: 2e26e052f8be2abd64e6d1dabfbd7be03f80ec18ccbc49562d31f617d0015fbdbcf0f9eed30346ea6ab789e0fdfe4337f033f8016efdbee0df5354751842080e + languageName: node + linkType: hard + "readable-stream@npm:^2.2.2": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" @@ -10999,14 +12468,14 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.0": - version: 1.5.0 - resolution: "regexp.prototype.flags@npm:1.5.0" +"regexp.prototype.flags@npm:^1.5.1": + version: 1.5.1 + resolution: "regexp.prototype.flags@npm:1.5.1" dependencies: call-bind: ^1.0.2 define-properties: ^1.2.0 - functions-have-names: ^1.2.3 - checksum: c541687cdbdfff1b9a07f6e44879f82c66bbf07665f9a7544c5fd16acdb3ec8d1436caab01662d2fbcad403f3499d49ab0b77fbc7ef29ef961d98cc4bc9755b4 + set-function-name: ^2.0.0 + checksum: 869edff00288442f8d7fa4c9327f91d85f3b3acf8cbbef9ea7a220345cf23e9241b6def9263d2c1ebcf3a316b0aa52ad26a43a84aa02baca3381717b3e307f47 languageName: node linkType: hard @@ -11036,19 +12505,19 @@ __metadata: linkType: hard "release-it@npm:^16.1.5": - version: 16.1.5 - resolution: "release-it@npm:16.1.5" + version: 16.2.1 + resolution: "release-it@npm:16.2.1" dependencies: "@iarna/toml": 2.2.5 "@octokit/rest": 19.0.13 async-retry: 1.3.3 chalk: 5.3.0 - cosmiconfig: 8.2.0 + cosmiconfig: 8.3.6 execa: 7.2.0 git-url-parse: 13.1.0 globby: 13.2.2 got: 13.0.0 - inquirer: 9.2.10 + inquirer: 9.2.11 is-ci: 3.0.1 issue-parser: 6.0.0 lodash: 4.17.21 @@ -11058,8 +12527,8 @@ __metadata: open: 9.1.0 ora: 7.0.1 os-name: 5.1.0 - promise.allsettled: 1.0.6 - proxy-agent: 6.3.0 + promise.allsettled: 1.0.7 + proxy-agent: 6.3.1 semver: 7.5.4 shelljs: 0.8.5 update-notifier: 6.0.2 @@ -11068,7 +12537,7 @@ __metadata: yargs-parser: 21.1.1 bin: release-it: bin/release-it.js - checksum: c20dcc3b0800510ecf1d2ef4b5486c445400fbd9954c16717c75f79df181e11ad724ecd86f8ff549aeaa4288e24d5bc82bfd873390468a618c416296cbe4ca1e + checksum: f2a3a8c8957372032cd2a523f698e7876c78e9e338345728bb3f303b1b19508991c764481dcd35cfb88d0d3620cbf3ed4dd5004271e94be6de90144526510bad languageName: node linkType: hard @@ -11101,19 +12570,6 @@ __metadata: languageName: node linkType: hard -"request-promise-native@npm:^1.0.5": - version: 1.0.9 - resolution: "request-promise-native@npm:1.0.9" - dependencies: - request-promise-core: 1.1.4 - stealthy-require: ^1.1.1 - tough-cookie: ^2.3.3 - peerDependencies: - request: ^2.34 - checksum: 3e2c694eefac88cb20beef8911ad57a275ab3ccbae0c4ca6c679fffb09d5fd502458aab08791f0814ca914b157adab2d4e472597c97a73be702918e41725ed69 - languageName: node - linkType: hard - "request-promise@npm:^4.2.2": version: 4.2.6 resolution: "request-promise@npm:4.2.6" @@ -11184,6 +12640,13 @@ __metadata: languageName: node linkType: hard +"resolve-alpn@npm:^1.2.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: f558071fcb2c60b04054c99aebd572a2af97ef64128d59bef7ab73bd50d896a222a056de40ffc545b633d99b304c259ea9d0c06830d5c867c34f0bfa60b8eae0 + languageName: node + linkType: hard + "resolve-from@npm:^3.0.0": version: 3.0.0 resolution: "resolve-from@npm:3.0.0" @@ -11215,15 +12678,16 @@ __metadata: linkType: hard "resolve@npm:^1.1.6": - version: 1.22.4 - resolution: "resolve@npm:1.22.4" + version: 1.22.6 + resolution: "resolve@npm:1.22.6" dependencies: + is-core-module: ^2.13.0 is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: 23f25174c2736ce24c6d918910e0d1f89b6b38fefa07a995dff864acd7863d59a7f049e691f93b4b2ee29696303390d921552b6d1b841ed4a8101f517e1d0124 + checksum: d13bf66d4e2ee30d291491f16f2fa44edd4e0cefb85d53249dd6f93e70b2b8c20ec62f01b18662e3cd40e50a7528f18c4087a99490048992a3bb954cf3201a5b languageName: node linkType: hard @@ -11244,15 +12708,16 @@ __metadata: linkType: hard "resolve@patch:resolve@^1.1.6#~builtin": - version: 1.22.4 - resolution: "resolve@patch:resolve@npm%3A1.22.4#~builtin::version=1.22.4&hash=c3c19d" + version: 1.22.6 + resolution: "resolve@patch:resolve@npm%3A1.22.6#~builtin::version=1.22.6&hash=c3c19d" dependencies: + is-core-module: ^2.13.0 is-core-module: ^2.13.0 path-parse: ^1.0.7 supports-preserve-symlinks-flag: ^1.0.0 bin: resolve: bin/resolve - checksum: c45f2545fdc4d21883861b032789e20aa67a2f2692f68da320cc84d5724cd02f2923766c5354b3210897e88f1a7b3d6d2c7c22faeead8eed7078e4c783a444bc + checksum: 9d3b3c67aefd12cecbe5f10ca4d1f51ea190891096497c43f301b086883b426466918c3a64f1bbf1788fabb52b579d58809614006c5d0b49186702b3b8fb746a languageName: node linkType: hard @@ -11285,6 +12750,16 @@ __metadata: languageName: node linkType: hard +"restore-cursor@npm:^4.0.0": + version: 4.0.0 + resolution: "restore-cursor@npm:4.0.0" + dependencies: + onetime: ^5.1.0 + signal-exit: ^3.0.2 + checksum: 5b675c5a59763bf26e604289eab35711525f11388d77f409453904e1e69c0d37ae5889295706b2c81d23bd780165084d040f9b68fffc32cc921519031c4fa4af + languageName: node + linkType: hard + "retry@npm:0.13.1": version: 0.13.1 resolution: "retry@npm:0.13.1" @@ -11369,6 +12844,15 @@ __metadata: languageName: node linkType: hard +"run-applescript@npm:^5.0.0": + version: 5.0.0 + resolution: "run-applescript@npm:5.0.0" + dependencies: + execa: ^5.0.0 + checksum: d00c2dbfa5b2d774de7451194b8b125f40f65fc183de7d9dcae97f57f59433586d3c39b9001e111c38bfa24c3436c99df1bb4066a2a0c90d39a8c4cd6889af77 + languageName: node + linkType: hard + "run-async@npm:^2.4.0": version: 2.4.1 resolution: "run-async@npm:2.4.1" @@ -11383,6 +12867,13 @@ __metadata: languageName: node linkType: hard +"run-async@npm:^3.0.0": + version: 3.0.0 + resolution: "run-async@npm:3.0.0" + checksum: 280c03d5a88603f48103fc6fd69f07fb0c392a1e0d319c34ec96a2516030e07ba06f79231a563c78698b882649c2fc1fda601bc84705f57d50efcd1fa506cfc0 + languageName: node + linkType: hard + "run-parallel-limit@npm:^1.1.0": version: 1.1.0 resolution: "run-parallel-limit@npm:1.1.0" @@ -11426,15 +12917,15 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.0.0": - version: 1.0.0 - resolution: "safe-array-concat@npm:1.0.0" +"safe-array-concat@npm:^1.0.0, safe-array-concat@npm:^1.0.1": + version: 1.0.1 + resolution: "safe-array-concat@npm:1.0.1" dependencies: call-bind: ^1.0.2 - get-intrinsic: ^1.2.0 + get-intrinsic: ^1.2.1 has-symbols: ^1.0.3 isarray: ^2.0.5 - checksum: f43cb98fe3b566327d0c09284de2b15fb85ae964a89495c1b1a5d50c7c8ed484190f4e5e71aacc167e16231940079b326f2c0807aea633d47cc7322f40a6b57f + checksum: 001ecf1d8af398251cbfabaf30ed66e3855127fbceee178179524b24160b49d15442f94ed6c0db0b2e796da76bb05b73bf3cc241490ec9c2b741b41d33058581 languageName: node linkType: hard @@ -11494,13 +12985,6 @@ __metadata: languageName: node linkType: hard -"scrypt-js@npm:2.0.4": - version: 2.0.4 - resolution: "scrypt-js@npm:2.0.4" - checksum: 679e8940953ebbef40863bfcc58f1d3058d4b7af0ca9bd8062d8213c30e14db59c6ebfc82a85fbd3b90b6d46b708be4c53b9c4bb200b6f50767dc08a846315a9 - languageName: node - linkType: hard - "scrypt-js@npm:3.0.1, scrypt-js@npm:^3.0.0": version: 3.0.1 resolution: "scrypt-js@npm:3.0.1" @@ -11536,6 +13020,15 @@ __metadata: languageName: node linkType: hard +"semver-diff@npm:^4.0.0": + version: 4.0.0 + resolution: "semver-diff@npm:4.0.0" + dependencies: + semver: ^7.3.5 + checksum: 4a958d6f76c7e7858268e1e2cf936712542441c9e003e561b574167279eee0a9bd55cc7eae1bfb31d3e7ad06a9fc370e7dd412fcfefec8c0daf1ce5aea623559 + languageName: node + linkType: hard + "semver@npm:7.3.4": version: 7.3.4 resolution: "semver@npm:7.3.4" @@ -11558,6 +13051,17 @@ __metadata: languageName: node linkType: hard +"semver@npm:7.5.4, semver@npm:^7.2.1, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2": + version: 7.5.4 + resolution: "semver@npm:7.5.4" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 + languageName: node + linkType: hard + "semver@npm:^5.5.0, semver@npm:^5.7.0": version: 5.7.2 resolution: "semver@npm:5.7.2" @@ -11601,10 +13105,14 @@ __metadata: languageName: node linkType: hard -"setimmediate@npm:1.0.4": - version: 1.0.4 - resolution: "setimmediate@npm:1.0.4" - checksum: 1d3726183ade73fa1c83bd562b05ae34e97802229d5b9292cde7ed03846524f04eb0fdd2131cc159103e3a7afb7c4e958b35bf960e3c4846fa50d94a3278be6f +"set-function-name@npm:^2.0.0": + version: 2.0.1 + resolution: "set-function-name@npm:2.0.1" + dependencies: + define-data-property: ^1.0.1 + functions-have-names: ^1.2.3 + has-property-descriptors: ^1.0.0 + checksum: 4975d17d90c40168eee2c7c9c59d023429f0a1690a89d75656306481ece0c3c1fb1ebcc0150ea546d1913e35fbd037bace91372c69e543e51fc5d1f31a9fa126 languageName: node linkType: hard @@ -11676,6 +13184,7 @@ __metadata: languageName: node linkType: hard +"shelljs@npm:0.8.5, shelljs@npm:^0.8.3": "shelljs@npm:0.8.5, shelljs@npm:^0.8.3": version: 0.8.5 resolution: "shelljs@npm:0.8.5" @@ -11700,6 +13209,7 @@ __metadata: languageName: node linkType: hard +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": "signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -11728,6 +13238,13 @@ __metadata: languageName: node linkType: hard +"slash@npm:^4.0.0": + version: 4.0.0 + resolution: "slash@npm:4.0.0" + checksum: da8e4af73712253acd21b7853b7e0dbba776b786e82b010a5bfc8b5051a1db38ed8aba8e1e8f400dd2c9f373be91eb1c42b66e91abb407ff42b10feece5e1d2d + languageName: node + linkType: hard + "slice-ansi@npm:^4.0.0": version: 4.0.0 resolution: "slice-ansi@npm:4.0.0" @@ -11757,14 +13274,14 @@ __metadata: languageName: node linkType: hard -"socks-proxy-agent@npm:^8.0.1": - version: 8.0.1 - resolution: "socks-proxy-agent@npm:8.0.1" +"socks-proxy-agent@npm:^8.0.2": + version: 8.0.2 + resolution: "socks-proxy-agent@npm:8.0.2" dependencies: - agent-base: ^7.0.1 + agent-base: ^7.0.2 debug: ^4.3.4 socks: ^2.7.1 - checksum: f6538fd16cb545094d20b9a1ae97bb2c4ddd150622ad7cc6b64c89c889d8847b7bac179757838ce5487cbac49a499537e3991c975fe13b152b76b10027470dfb + checksum: 4fb165df08f1f380881dcd887b3cdfdc1aba3797c76c1e9f51d29048be6e494c5b06d68e7aea2e23df4572428f27a3ec22b3d7c75c570c5346507433899a4b6d languageName: node linkType: hard @@ -11809,6 +13326,7 @@ __metadata: languageName: node linkType: hard +"solhint@npm:3.4.1": "solhint@npm:3.4.1": version: 3.4.1 resolution: "solhint@npm:3.4.1" @@ -11871,7 +13389,7 @@ __metadata: languageName: node linkType: hard -"solidity-ast@npm:^0.4.49": +"solidity-ast@npm:^0.4.49, solidity-ast@npm:^0.4.51": version: 0.4.52 resolution: "solidity-ast@npm:0.4.52" dependencies: @@ -11920,8 +13438,8 @@ __metadata: linkType: hard "solidity-coverage@npm:^0.8.2, solidity-coverage@npm:^0.8.3": - version: 0.8.4 - resolution: "solidity-coverage@npm:0.8.4" + version: 0.8.5 + resolution: "solidity-coverage@npm:0.8.5" dependencies: "@ethersproject/abi": ^5.0.9 "@solidity-parser/parser": ^0.16.0 @@ -11935,7 +13453,7 @@ __metadata: globby: ^10.0.1 jsonschema: ^1.2.4 lodash: ^4.17.15 - mocha: 7.1.2 + mocha: 10.2.0 node-emoji: ^1.10.0 pify: ^4.0.1 recursive-readdir: ^2.2.2 @@ -11947,7 +13465,7 @@ __metadata: hardhat: ^2.11.0 bin: solidity-coverage: plugins/bin.js - checksum: 263089376d05f572350a2e47b61b2c604b3b5deedf4547cb0334342ecf6b732f823c069790e21063a56502a0d1fb9051a6f7bae1b990e2917af56fc94ac96759 + checksum: c9ca4deda9383c1db425117e72677f8908dcb2263ad41cfc1821c96afcfd5e8070146b87cd2c4b0812612fb707896928c07b776347143db838e486b4c938b394 languageName: node linkType: hard @@ -11961,6 +13479,7 @@ __metadata: languageName: node linkType: hard +"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": "source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" @@ -12006,10 +13525,14 @@ __metadata: linkType: hard "ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" version: 10.0.5 resolution: "ssri@npm:10.0.5" dependencies: minipass: ^7.0.3 + checksum: 0a31b65f21872dea1ed3f7c200d7bc1c1b91c15e419deca14f282508ba917cbb342c08a6814c7f68ca4ca4116dd1a85da2bbf39227480e50125a1ceffeecb750 + minipass: ^7.0.3 checksum: 0a31b65f21872dea1ed3f7c200d7bc1c1b91c15e419deca14f282508ba917cbb342c08a6814c7f68ca4ca4116dd1a85da2bbf39227480e50125a1ceffeecb750 languageName: node linkType: hard @@ -12039,6 +13562,15 @@ __metadata: languageName: node linkType: hard +"stdin-discarder@npm:^0.1.0": + version: 0.1.0 + resolution: "stdin-discarder@npm:0.1.0" + dependencies: + bl: ^5.0.0 + checksum: 85131f70ae2830144133b7a6211d56f9ac2603573f4af3d0b66e828af5e13fcdea351f9192f86bb7fed2c64604c8097bf36d50cb77d54e898ce4604c3b7b6b8f + languageName: node + linkType: hard + "stealthy-require@npm:^1.1.1": version: 1.1.1 resolution: "stealthy-require@npm:1.1.1" @@ -12055,6 +13587,15 @@ __metadata: languageName: node linkType: hard +"stop-iteration-iterator@npm:^1.0.0": + version: 1.0.0 + resolution: "stop-iteration-iterator@npm:1.0.0" + dependencies: + internal-slot: ^1.0.4 + checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 + languageName: node + linkType: hard + "stream-transform@npm:^2.1.3": version: 2.1.3 resolution: "stream-transform@npm:2.1.3" @@ -12064,13 +13605,6 @@ __metadata: languageName: node linkType: hard -"streamsearch@npm:^1.1.0": - version: 1.1.0 - resolution: "streamsearch@npm:1.1.0" - checksum: 1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942 - languageName: node - linkType: hard - "string-format@npm:^2.0.0": version: 2.0.0 resolution: "string-format@npm:2.0.0" @@ -12085,6 +13619,13 @@ __metadata: languageName: node linkType: hard +"string-template@npm:^1.0.0": + version: 1.0.0 + resolution: "string-template@npm:1.0.0" + checksum: 15b0e8616ff25f3ddcd42e4a58a6833cc7be81029f97afc7b8f8d2e7c4d482a136e67399d207b7d2c31080e7a88266c670131a59e50ebc482bfeddb06b3a4215 + languageName: node + linkType: hard + "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -12139,36 +13680,36 @@ __metadata: languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.7": - version: 1.2.7 - resolution: "string.prototype.trim@npm:1.2.7" +"string.prototype.trim@npm:^1.2.8": + version: 1.2.8 + resolution: "string.prototype.trim@npm:1.2.8" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - checksum: 05b7b2d6af63648e70e44c4a8d10d8cc457536df78b55b9d6230918bde75c5987f6b8604438c4c8652eb55e4fc9725d2912789eb4ec457d6995f3495af190c09 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + checksum: 49eb1a862a53aba73c3fb6c2a53f5463173cb1f4512374b623bcd6b43ad49dd559a06fb5789bdec771a40fc4d2a564411c0a75d35fb27e76bbe738c211ecff07 languageName: node linkType: hard -"string.prototype.trimend@npm:^1.0.6": - version: 1.0.6 - resolution: "string.prototype.trimend@npm:1.0.6" +"string.prototype.trimend@npm:^1.0.7": + version: 1.0.7 + resolution: "string.prototype.trimend@npm:1.0.7" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - checksum: 0fdc34645a639bd35179b5a08227a353b88dc089adf438f46be8a7c197fc3f22f8514c1c9be4629b3cd29c281582730a8cbbad6466c60f76b5f99cf2addb132e + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + checksum: 2375516272fd1ba75992f4c4aa88a7b5f3c7a9ca308d963bcd5645adf689eba6f8a04ebab80c33e30ec0aefc6554181a3a8416015c38da0aa118e60ec896310c languageName: node linkType: hard -"string.prototype.trimstart@npm:^1.0.6": - version: 1.0.6 - resolution: "string.prototype.trimstart@npm:1.0.6" +"string.prototype.trimstart@npm:^1.0.7": + version: 1.0.7 + resolution: "string.prototype.trimstart@npm:1.0.7" dependencies: call-bind: ^1.0.2 - define-properties: ^1.1.4 - es-abstract: ^1.20.4 - checksum: 89080feef416621e6ef1279588994305477a7a91648d9436490d56010a1f7adc39167cddac7ce0b9884b8cdbef086987c4dcb2960209f2af8bac0d23ceff4f41 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + checksum: 13d0c2cb0d5ff9e926fa0bec559158b062eed2b68cd5be777ffba782c96b2b492944e47057274e064549b94dd27cf81f48b27a31fee8af5b574cff253e7eb613 languageName: node linkType: hard @@ -12217,6 +13758,7 @@ __metadata: languageName: node linkType: hard +"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": "strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": version: 7.1.0 resolution: "strip-ansi@npm:7.1.0" @@ -12254,6 +13796,20 @@ __metadata: languageName: node linkType: hard +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + +"strip-final-newline@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-final-newline@npm:3.0.0" + checksum: 23ee263adfa2070cd0f23d1ac14e2ed2f000c9b44229aec9c799f1367ec001478469560abefd00c5c99ee6f0b31c137d53ec6029c53e9f32a93804e18c201050 + languageName: node + linkType: hard + "strip-hex-prefix@npm:1.0.0": version: 1.0.0 resolution: "strip-hex-prefix@npm:1.0.0" @@ -12263,6 +13819,7 @@ __metadata: languageName: node linkType: hard +"strip-json-comments@npm:2.0.1, strip-json-comments@npm:~2.0.1": "strip-json-comments@npm:2.0.1, strip-json-comments@npm:~2.0.1": version: 2.0.1 resolution: "strip-json-comments@npm:2.0.1" @@ -12411,8 +13968,8 @@ __metadata: linkType: hard "tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.1.15 - resolution: "tar@npm:6.1.15" + version: 6.2.0 + resolution: "tar@npm:6.2.0" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 @@ -12420,7 +13977,7 @@ __metadata: minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: f23832fceeba7578bf31907aac744ae21e74a66f4a17a9e94507acf460e48f6db598c7023882db33bab75b80e027c21f276d405e4a0322d58f51c7088d428268 + checksum: db4d9fe74a2082c3a5016630092c54c8375ff3b280186938cfd104f2e089c4fd9bad58688ef6be9cf186a889671bf355c7cda38f09bbf60604b281715ca57f5c languageName: node linkType: hard @@ -12464,6 +14021,13 @@ __metadata: languageName: node linkType: hard +"titleize@npm:^3.0.0": + version: 3.0.0 + resolution: "titleize@npm:3.0.0" + checksum: 71fbbeabbfb36ccd840559f67f21e356e1d03da2915b32d2ae1a60ddcc13a124be2739f696d2feb884983441d159a18649e8d956648d591bdad35c430a6b6d28 + languageName: node + linkType: hard + "tmp@npm:0.0.33, tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33" @@ -12628,6 +14192,10 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad "tslib@npm:^2.0.1, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.5.0": version: 2.6.2 resolution: "tslib@npm:2.6.2" @@ -12701,7 +14269,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:^4.0.0, type-detect@npm:^4.0.5": +"type-detect@npm:^4.0.0, type-detect@npm:^4.0.8": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 62b5628bff67c0eb0b66afa371bd73e230399a8d2ad30d852716efcc4656a7516904570cd8631a49a3ce57c10225adf5d0cbdcb47f6b0255fe6557c453925a15 @@ -12743,7 +14311,7 @@ __metadata: languageName: node linkType: hard -"typechain@npm:^8.2.0": +"typechain@npm:^8.1.1, typechain@npm:^8.2.0": version: 8.3.1 resolution: "typechain@npm:8.3.1" dependencies: @@ -12821,6 +14389,15 @@ __metadata: languageName: node linkType: hard +"typedarray-to-buffer@npm:^3.1.5": + version: 3.1.5 + resolution: "typedarray-to-buffer@npm:3.1.5" + dependencies: + is-typedarray: ^1.0.0 + checksum: 99c11aaa8f45189fcfba6b8a4825fd684a321caa9bd7a76a27cf0c7732c174d198b99f449c52c3818107430b5f41c0ccbbfb75cb2ee3ca4a9451710986d61a60 + languageName: node + linkType: hard + "typedarray@npm:^0.0.6": version: 0.0.6 resolution: "typedarray@npm:0.0.6" @@ -12848,6 +14425,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:^5.0.4": + version: 5.2.2 + resolution: "typescript@npm:5.2.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c + languageName: node + linkType: hard + "typescript@patch:typescript@5.0.4#~builtin": version: 5.0.4 resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=b5f058" @@ -12868,6 +14455,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@^5.0.4#~builtin": + version: 5.2.2 + resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=5da071" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 07106822b4305de3f22835cbba949a2b35451cad50888759b6818421290ff95d522b38ef7919e70fb381c5fe9c1c643d7dea22c8b31652a717ddbd57b7f4d554 + languageName: node + linkType: hard + "typical@npm:^4.0.0": version: 4.0.0 resolution: "typical@npm:4.0.0" @@ -12904,11 +14501,11 @@ __metadata: linkType: hard "undici@npm:^5.14.0": - version: 5.23.0 - resolution: "undici@npm:5.23.0" + version: 5.25.4 + resolution: "undici@npm:5.25.4" dependencies: - busboy: ^1.6.0 - checksum: 906ca4fb1d47163d2cee2ecbbc664a1d92508a2cdf1558146621109f525c983a83597910b36e6ba468240e95259be5939cea6babc99fc0c36360b16630f66784 + "@fastify/busboy": ^2.0.0 + checksum: 654da161687de893127a685be61a19cb5bae42f4595c316ebf633929d871ac3bcd33edcb74156cea90655dfcd100bfe9b53a4f4749d52fc6ad2232f49a6ca8ab languageName: node linkType: hard @@ -12953,6 +14550,22 @@ __metadata: languageName: node linkType: hard +"unique-string@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-string@npm:3.0.0" + dependencies: + crypto-random-string: ^4.0.0 + checksum: 1a1e2e7d02eab1bb10f720475da735e1990c8a5ff34edd1a3b6bc31590cb4210b7a1233d779360cc622ce11c211e43afa1628dd658f35d3e6a89964b622940df + languageName: node + linkType: hard + +"universal-user-agent@npm:^6.0.0": + version: 6.0.0 + resolution: "universal-user-agent@npm:6.0.0" + checksum: 5092bbc80dd0d583cef0b62c17df0043193b74f425112ea6c1f69bc5eda21eeec7a08d8c4f793a277eb2202ffe9b44bec852fa3faff971234cd209874d1b79ef + languageName: node + linkType: hard + "universalify@npm:^0.1.0": version: 0.1.2 resolution: "universalify@npm:0.1.2" @@ -13003,6 +14616,35 @@ __metadata: languageName: node linkType: hard +"untildify@npm:^4.0.0": + version: 4.0.0 + resolution: "untildify@npm:4.0.0" + checksum: 39ced9c418a74f73f0a56e1ba4634b4d959422dff61f4c72a8e39f60b99380c1b45ed776fbaa0a4101b157e4310d873ad7d114e8534ca02609b4916bb4187fb9 + languageName: node + linkType: hard + +"update-notifier@npm:6.0.2": + version: 6.0.2 + resolution: "update-notifier@npm:6.0.2" + dependencies: + boxen: ^7.0.0 + chalk: ^5.0.1 + configstore: ^6.0.0 + has-yarn: ^3.0.0 + import-lazy: ^4.0.0 + is-ci: ^3.0.1 + is-installed-globally: ^0.4.0 + is-npm: ^6.0.0 + is-yarn-global: ^0.4.0 + latest-version: ^7.0.0 + pupa: ^3.1.0 + semver: ^7.3.7 + semver-diff: ^4.0.0 + xdg-basedir: ^5.1.0 + checksum: 4bae7b3eca7b2068b6b87dde88c9dad24831fa913a5b83ecb39a7e4702c93e8b05fd9bcac5f1a005178f6e5dc859e0b3817ddda833d2a7ab92c6485e078b3cc8 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -13019,6 +14661,13 @@ __metadata: languageName: node linkType: hard +"url-join@npm:5.0.0": + version: 5.0.0 + resolution: "url-join@npm:5.0.0" + checksum: 5921384a8ad4395b49ce4b50aa26efbc429cebe0bc8b3660ad693dd12fd859747b5369be0443e60e53a7850b2bc9d7d0687bcb94386662b40e743596bbf38101 + languageName: node + linkType: hard + "url-join@npm:^4.0.0": version: 4.0.1 resolution: "url-join@npm:4.0.1" @@ -13047,13 +14696,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:2.0.1": - version: 2.0.1 - resolution: "uuid@npm:2.0.1" - checksum: e129e494e33cededdfc2cefbd63da966344b873bbfd3373a311b0acc2e7ab53d68b2515879444898867d84b863e44939e852484b9f3a54c4fd86d985a7dadb8d - languageName: node - linkType: hard - "uuid@npm:^3.3.2": version: 3.4.0 resolution: "uuid@npm:3.4.0" @@ -13079,6 +14721,7 @@ __metadata: languageName: node linkType: hard +"v8-compile-cache@npm:2.3.0": "v8-compile-cache@npm:2.3.0": version: 2.3.0 resolution: "v8-compile-cache@npm:2.3.0" @@ -13093,6 +14736,13 @@ __metadata: languageName: node linkType: hard +"v8-compile-cache@npm:^2.0.3": + version: 2.4.0 + resolution: "v8-compile-cache@npm:2.4.0" + checksum: 8eb6ddb59d86f24566503f1e6ca98f3e6f43599f05359bd3ab737eaaf1585b338091478a4d3d5c2646632cf8030288d7888684ea62238cdce15a65ae2416718f + languageName: node + linkType: hard + "verror@npm:1.10.0": version: 1.10.0 resolution: "verror@npm:1.10.0" @@ -13118,16 +14768,16 @@ __metadata: linkType: hard "vscode-languageserver-textdocument@npm:^1.0.3": - version: 1.0.10 - resolution: "vscode-languageserver-textdocument@npm:1.0.10" - checksum: 605ff0662535088567a145b48d28f0c41844d28269fa0b3fca3a1e179dd14baf7181150b274bf3840ef2a043ed8474a9227aaf169a6fae574516349a1b371a18 + version: 1.0.11 + resolution: "vscode-languageserver-textdocument@npm:1.0.11" + checksum: ea7cdc9d4ffaae5952071fa11d17d714215a76444e6936c9359f94b9ba3222a52a55edb5bd5928bd3e9712b900a9f175bb3565ec1c8923234fe3bd327584bafb languageName: node linkType: hard "vscode-languageserver-types@npm:^3.16.0": - version: 3.17.3 - resolution: "vscode-languageserver-types@npm:3.17.3" - checksum: fbc8221297261f659a6482875ff2a419dc9d55965dc53745797da569ff9f819cd832e6f2699017baadd946548bbfe212e3f6971f3d960f12dc0ee9c629dacc07 + version: 3.17.5 + resolution: "vscode-languageserver-types@npm:3.17.5" + checksum: 79b420e7576398d396579ca3a461c9ed70e78db4403cd28bbdf4d3ed2b66a2b4114031172e51fad49f0baa60a2180132d7cb2ea35aa3157d7af3c325528210ac languageName: node linkType: hard @@ -13161,19 +14811,40 @@ __metadata: languageName: node linkType: hard +"wcwidth@npm:^1.0.1": + version: 1.0.1 + resolution: "wcwidth@npm:1.0.1" + dependencies: + defaults: ^1.0.3 + checksum: 814e9d1ddcc9798f7377ffa448a5a3892232b9275ebb30a41b529607691c0491de47cba426e917a4d08ded3ee7e9ba2f3fe32e62ee3cd9c7d3bafb7754bd553c + languageName: node + linkType: hard + +"web-streams-polyfill@npm:^3.0.3": + version: 3.2.1 + resolution: "web-streams-polyfill@npm:3.2.1" + checksum: b119c78574b6d65935e35098c2afdcd752b84268e18746606af149e3c424e15621b6f1ff0b42b2676dc012fc4f0d313f964b41a4b5031e525faa03997457da02 + languageName: node + linkType: hard + "web3-utils@npm:^1.3.6": + version: 1.10.2 + resolution: "web3-utils@npm:1.10.2" version: 1.10.2 resolution: "web3-utils@npm:1.10.2" dependencies: + "@ethereumjs/util": ^8.1.0 "@ethereumjs/util": ^8.1.0 bn.js: ^5.2.1 ethereum-bloom-filters: ^1.0.6 ethereum-cryptography: ^2.1.2 + ethereum-cryptography: ^2.1.2 ethjs-unit: 0.1.6 number-to-bn: 1.7.0 randombytes: ^2.1.0 utf8: 3.0.0 checksum: a5f8db69603fdd5e984aa6407f47f7a4e0dab83af42e10de25a6d9eeaf2e7d4d18fe665b569e364b2e916233fb73b26cc70ff0d730e7909720118c4790dfb043 + checksum: a5f8db69603fdd5e984aa6407f47f7a4e0dab83af42e10de25a6d9eeaf2e7d4d18fe665b569e364b2e916233fb73b26cc70ff0d730e7909720118c4790dfb043 languageName: node linkType: hard @@ -13214,7 +14885,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.10, which-typed-array@npm:^1.1.11": +"which-typed-array@npm:^1.1.11": version: 1.1.11 resolution: "which-typed-array@npm:1.1.11" dependencies: @@ -13292,6 +14963,31 @@ __metadata: languageName: node linkType: hard +"widest-line@npm:^4.0.1": + version: 4.0.1 + resolution: "widest-line@npm:4.0.1" + dependencies: + string-width: ^5.0.1 + checksum: 64c48cf27171221be5f86fc54b94dd29879165bdff1a7aa92dde723d9a8c99fb108312768a5d62c8c2b80b701fa27bbd36a1ddc58367585cd45c0db7920a0cba + languageName: node + linkType: hard + +"wildcard-match@npm:5.1.2": + version: 5.1.2 + resolution: "wildcard-match@npm:5.1.2" + checksum: d39ea5dcb807e9c515092adbb54c9a03743c9310e875919da5c25f268ed0c566a391c4afdca876e25d836fbbf5a71ce4a6e68ad034c24ce9751b5b60b4683bb9 + languageName: node + linkType: hard + +"windows-release@npm:^5.0.1": + version: 5.1.1 + resolution: "windows-release@npm:5.1.1" + dependencies: + execa: ^5.1.1 + checksum: 8d15388ccfcbacb96d551f4a692a0a0930a12d2283d140d0a00ea0f6c4f950907cb8055a2cff8650d8bcd5125585338ff0f21a0d7661a30c1d67b6729d13b6b8 + languageName: node + linkType: hard + "wonka@npm:^4.0.14": version: 4.0.15 resolution: "wonka@npm:4.0.15" @@ -13377,6 +15073,17 @@ __metadata: languageName: node linkType: hard +"wrap-ansi@npm:^6.2.0": + version: 6.2.0 + resolution: "wrap-ansi@npm:6.2.0" + dependencies: + ansi-styles: ^4.0.0 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + checksum: 6cd96a410161ff617b63581a08376f0cb9162375adeb7956e10c8cd397821f7eb2a6de24eb22a0b28401300bf228c86e50617cd568209b5f6775b93c97d2fe3a + languageName: node + linkType: hard + "wrap-ansi@npm:^8.1.0": version: 8.1.0 resolution: "wrap-ansi@npm:8.1.0" @@ -13407,6 +15114,18 @@ __metadata: languageName: node linkType: hard +"write-file-atomic@npm:^3.0.3": + version: 3.0.3 + resolution: "write-file-atomic@npm:3.0.3" + dependencies: + imurmurhash: ^0.1.4 + is-typedarray: ^1.0.0 + signal-exit: ^3.0.2 + typedarray-to-buffer: ^3.1.5 + checksum: c55b24617cc61c3a4379f425fc62a386cc51916a9b9d993f39734d005a09d5a4bb748bc251f1304e7abd71d0a26d339996c275955f527a131b1dcded67878280 + languageName: node + linkType: hard + "ws@npm:7.4.6": version: 7.4.6 resolution: "ws@npm:7.4.6" @@ -13459,13 +15178,6 @@ __metadata: languageName: node linkType: hard -"xmlhttprequest@npm:1.8.0": - version: 1.8.0 - resolution: "xmlhttprequest@npm:1.8.0" - checksum: c891cf0d7884b4f5cce835aa01f1965727cd352cbd2d7a2e0605bf11ec99ae2198364cca54656ec8b2581a5704dee6c2bf9911922a0ff2a71b613455d32e81b7 - languageName: node - linkType: hard - "xtend@npm:^4.0.1, xtend@npm:^4.0.2, xtend@npm:~4.0.0": version: 4.0.2 resolution: "xtend@npm:4.0.2"